Skip to main content

Command Palette

Search for a command to run...

JavaScript-30-Day-5

Updated
โ€ข6 min readโ€ขView as Markdown
JavaScript-30-Day-5

ss.png

click for project demo

So DAY-5 of javascript30 heavily focused on the CSS flex property.

Before starting I would like to mention Wes has another one of these tutorials like javascript30 for flex called flexbox.io. I think I might try it out after I am done with javascript30.

In this lesson, you make a photo gallery page where each image is shown and clicking on an image will expand it to take up more space to get a better look. With the expanding image, some text also animates in from the top and bottom giving a nice, smooth feel to the whole thing.

This is initial html setup that was given:

<div class="panels">
      <div class="panel panel1">
        <p>Hey</p>
        <p>Let's</p>
        <p>Dance</p>
      </div>
      <div class="panel panel2">
        <p>Give</p>
        <p>Take</p>
        <p>Receive</p>
      </div>
      <div class="panel panel3">
        <p>Experience</p>
        <p>It</p>
        <p>Today</p>
      </div>
      <div class="panel panel4">
        <p>Give</p>
        <p>All</p>
        <p>You can</p>
      </div>
      <div class="panel panel5">
        <p>Life</p>
        <p>In</p>
        <p>Motion</p>
      </div>
    </div>

##CSS

We started off by adding a display:flex on the .panels class so that all 5 panels are displayed side by side.

But this left a lot of empty space on the page so to make the panels cover the full page equally we go to each individual panel and tell them we've got all this extra space here so split it amongst yourselves and we do so by adding a flex:1 to the .panel class.

flex:1 means each of the panels is going to evenly distribute the extra space among each other.

I did more research about flex and this is what is learned:

flex property

According to w3School, flex property is a shorthand version of another 3 properties:

The flex property is a shorthand property for:

  • flex-grow
  • flex-shrink
  • flex-basis

The flex property sets the flexible length on flexible items.

Note: If the element is not a flexible item, the flex property has no effect.

Let's see these properties closer:

flex-grow

According to w3School:

The flex-grow property specifies how much the item will grow relative to the rest of the flexible items inside the same container.

What does it mean?

If I have three panels:

    <div class="panel-1"></div>
    <div class="panel-2"></div>
    <div class="panel-3"></div>

We can set what of them is greater than other relatiely with each other, using flex-grow:

    .panel-1:hover{flex-grow: 1;}
    .panel-2:hover{flex-grow: 2;}
    .panel-3:hover{flex-grow: 3;}

flex-shrink

According to w3School:

The flex-shrink property specifies how the item will shrink relative to the rest of the flexible items inside the same container.

What does it mean?

Using the same last HTML panel example, we can set how and what of these panels is shrunk. Here I chose the middle panel:

    .panel-3:hover{flex-shrink: 2;}

flex-basis

According to w3School:

The flex-basis property specifies the initial length of a flexible item.

What does it mean?

Using the same last HTML panel example, we can set the length of a flex item. Here I chose the middle panel to be initially bigger than others:

.panel-1:hover{flex-basis: 15%;}
.panel-2:hover{flex-basis: 70%;}
.panel-3:hover{flex-basis: 15%;}
  • Next thing I learned was when we tried to center align the text where I came to know that an element in CSS can both be a flex-item and flex-container that is we can nest multiple flex together.

  • Now we'll take the upper text all the way up and lower text all the way down and for that we used translateY() but we want the words to comeback when clicked and expanded so we add another tranlateY() this time with a .open-active class which we would add to the panels when clicked using JavaScript.

.panel > *:first-child {
        transform: translateY(-100%);
      }
      .panel.open-active > *:first-child {
        transform: translateY(0);
      }
      .panel > *:last-child {
        transform: translateY(100%);
      }
      .panel.open-active > *:last-child {
        transform: translateY(0);
      }

JavaScript

  • first we use querySelectorAll() to get a NodeList of all the panels.

    const panels = document.querySelectorAll(".panel");
    
  • now we use forEach() to add an click event listener to all panels

    panels.forEach((panel) => panel.addEventListener("click", toggleOpen));
    

this would add .open() class to panels upon getting clicked

function toggleOpen() {
        this.classList.toggle("open");
      }

and this is what is in the .open() class. This would enlarge the size of the panel.

.panel.open {
        font-size: 40px;
        flex: 5;
      }

This was my first time using classList.toggle(). Here is what w3schools says:

toggle(class, true|false) Toggles between a class name for an element.

The first parameter removes the specified class from an element, and returns false. If the class does not exist, it is added to the element, and the return value is true.

The optional second parameter is a Boolean value that forces the class to be added or removed, regardless of whether or not it already existed. For example:

Remove a class: element.classList.toggle("classToRemove", false); Add a class: element.classList.toggle("classToAdd", true);

Accordding to MDN:

The toggle() method of the DOMTokenList interface removes a given token from the list and returns false. If token doesn't exist it's added and the function returns true.

Here we have the function coded by Wes to show the hidden words when we click on image:

    function toggleOpen() {
        this.classList.toggle('open');
    }

According with what we read before about toggle() method, this function verifies if the class open exists or not in the classList of that element, which is being verified:

  • If the class open exists on the classList, this class is removed from the list and returns false.
  • If the class open does not exist on the classList, the open class is added in the list and returns true.
  • next event listener we are going to add is transitionend which would cause the text to appear by adding the .open-active class as soon as the panel finishes expanding transition.
    panels.forEach((panel) =>
          panel.addEventListener("transitionend", toggleActive)
        );
    

but now instead of simply adding .open-active class we have to check first because more than one transition is ending here. We can check that out by using:

function toggleActive(e) {
console.log(e.propertyName);
}

in our case flex-grow and font-size events are ending. But we need to concern ourselves with only flex-grow.

Now Wes mentioned one important thing here:

Safari transitionend event.propertyName === flex Chrome + FF transitionend event.propertyName === flex-grow

So to cover our bases we'll check if the transition includes the word flex instead of explicitly checking for flex-grow

function toggleActive(e) {
        if (e.propertyName.includes("flex")) {
          this.classList.toggle("open-active");
        }
      }

and with this todays project was done.

GitHub repo: {% github cenacrharsh/JS-30-DAY-5 no-readme %}

###Blog on Day-4 of javascript30 {% link https://dev.to/cenacr007_harsh/javascript-30-day-4-13k0 %}

###Blog on Day-3 of javascript30 {% link https://dev.to/cenacr007_harsh/javascript-30-day-3-29o6 %}

###Blog on Day-2 of javascript30 {% link https://dev.to/cenacr007_harsh/javascript-30-day-2-1dmm %}

Follow me on Twitter Follow me on Linkedin

DEV Profile

{% user cenacr007_harsh %}

You can also do the challenge at javascript30

Thanks WesBos to share this with us! ๐Ÿ˜Š๐Ÿ’–

Please comment and let me know your views

##Thank You!

11 views

More from this blog

Kumar Harsh's Blog

34 posts