DEV Community

Cover image for JavaScript-30-Day-5
KUMAR HARSH
KUMAR HARSH

Posted on • Updated on

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;}
Enter fullscreen mode Exit fullscreen mode

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;}
Enter fullscreen mode Exit fullscreen mode

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%;}
Enter fullscreen mode Exit fullscreen mode
  • 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);
      }
Enter fullscreen mode Exit fullscreen mode

JavaScript

  • first we use querySelectorAll() to get a NodeList of all the panels.
const panels = document.querySelectorAll(".panel");
Enter fullscreen mode Exit fullscreen mode
  • now we use forEach() to add an click event listener to all panels
panels.forEach((panel) => panel.addEventListener("click", toggleOpen));
Enter fullscreen mode Exit fullscreen mode

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

function toggleOpen() {
        this.classList.toggle("open");
      }
Enter fullscreen mode Exit fullscreen mode

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

.panel.open {
        font-size: 40px;
        flex: 5;
      }
Enter fullscreen mode Exit fullscreen mode

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');
    }
Enter fullscreen mode Exit fullscreen mode

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)
      );
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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");
        }
      }
Enter fullscreen mode Exit fullscreen mode

and with this todays project was done.

GitHub repo:

Blog on Day-4 of javascript30

Blog on Day-3 of javascript30

Blog on Day-2 of javascript30

Follow me on Twitter
Follow me on Linkedin

DEV Profile

cenacr007_harsh image

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!

Top comments (6)

Collapse
 
rash123 profile image
RASHMI VERMA

EPIC

Collapse
 
cenacr007_harsh profile image
KUMAR HARSH

thanks a lot.

Collapse
 
rohitk570 profile image
ROHIT KUMAR

GREAT

Collapse
 
cenacr007_harsh profile image
KUMAR HARSH

thanks

Collapse
 
devendrapratapp profile image
Devendra Pratap

Good job bud 👍🏽

Collapse
 
cenacr007_harsh profile image
KUMAR HARSH

thanks