CodeNewbie Community 🌱

Cover image for Commit18 //#JavaScript30 - Day 5 [Flex Panels Image Gallery]
Janet Webster
Janet Webster

Posted on

Commit18 //#JavaScript30 - Day 5 [Flex Panels Image Gallery]

Photo of Flex Panels Image Gallery with my own photography


I am learning with Skillcrush. Please check them out and consider signing up if you're looking to break into tech! Receive $250 off your course by using the link above. Use the coupon code: TWIXMIXY
NOTE: this discount is for Break Into Tech + Get Hired package exclusively. It's the same program I am participating in!


Today's challenge comes from JavaScript30.

Coming off a relatively busy weekend from volunteering my time on Saturday to being at roller derby practice for half the day Sunday.

Feeling pretty tired today after getting up early to workout at 8AM. I am in the process of "body building". Not really body building though. I'm lifting weights a couple times a week with a trainer to be able to build some muscle and support myself in playing roller derby.

Overall it's felt good to add on some pounds, but I'm definitely struggling to consume enough calories to support this process. If you have ever gone through something like this I'd love to hear your tips and tricks to sustainable bulking up. Thanks!

JavaScript30 - Day 5

flexbox.io - a website by the instructor on how to do CSS flexboxes.

To begin we are going to cover a lot of CSS, so let me try to explain what I understand is being taught.

Basically we are using JavaScript to transition between CSS settings to create the flex/animation look.

Prior to adding the display:flex to the .panels, this is what it looks like.

Initial view of flex panels

And here's how it looks after we add this class.

Flex panels after display added

As you can see, we have some extra space, so now we want to tell each panel to split the difference. So the instructor says to add flex: 1 to the individual .panel.

Flex 1 added to each panel

He doesn't yet explain why this works, but says he'll circle back around to it.

Next he recommends adding a temporary border to the text elements in the panels, so you can see how they are flexing and functioning.

Panel text elements

I'm not sure why this is .panel > *. He doesn't really explain it from what I'm seeing, so if you know why please comment below!

To start moving these text elements to where we want them, we add more code to the .panel.

.panel classes

justify-content and align-items basically just re-state what the text is already doing, so I'm not quite sure why they are being used. Guess I will need to take that flexbox.io course at some point.

Then we get to display: flex and that does what you see in the image above. It allows the text to default to the middle. But it's now placing the words on one line basically, instead of making them go top to bottom like we want.

To fix this, we will add flex-direction: column and now they are vertically centered in the middle.

flex direction column

Now we want each of the text elements to take up 1/3 of the page. So we will add flex: 1 0 auto to the .panel > *, which he's called the flex items.

Flex 1/3

Then we add display: flex which defaults all the text to the left.

Display flex

Now we add justify-content: center and align-items: center to the special .panel > * (flex items).

Justify and align center

Now everything is centered up, through all of the nesting flexbox work. Why does it have to be so complicated?

The next steps get pretty complicated in the CSS, but I will try my best. What we are trying to do is push the top and bottom text to be off screen, so we can create an animation effect.

Adding a new class for the first-child .panel > *, pushes the top text off the screen.

first-child off screen

Same thing with the last-child.

.panel > *:last-child { transform: translateY(100%); }
Enter fullscreen mode Exit fullscreen mode

What we will do is use the JavaScript to remove these classes, so it will move on and off the screen.

.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

The last aspect of the CSS we want to add is making the text larger when clicking into the panel.

We will use the .panel.open class to accomplish this.

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

To do this we are basing it off of the initial flex: 1 we created and it's multiplying it times 5 to increase it's size.

This is going off of transitions that are already pre-set for this challenge. Here is the code for the .panel so you can see what the transition looks like. It's what's creating that animated effect.

    .panel {
      background: #6B0F9C;
      box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);
      color: white;
      text-align: center;
      align-items: center;
      /* Safari transitionend event.propertyName === flex */
      /* Chrome + FF transitionend event.propertyName === flex-grow */
      transition:
        font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
        flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
        background 0.2s;
      font-size: 20px;
      background-size: cover;
      background-position: center;
      flex: 1;
      justify-content: center;
      align-items: center;
      display: flex;
      flex-direction: column;
    }
Enter fullscreen mode Exit fullscreen mode

Time to move on to the JavaScript!

To begin we will select all the .panels by using querySelectorAll.

  <script>
    const panels = document.querySelectorAll('.panel');
  </script>
Enter fullscreen mode Exit fullscreen mode

Then we will need to write a function to toggle the open of a panel.

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

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

Enter fullscreen mode Exit fullscreen mode

Now the panel is expanding.

Panel expanding

What this does is it adds the class to that panel clicked. Then if you click on it again, it removes the class.

Next we need to bring in the words from the top and bottom.

We'll do this by duplicated our event listener and making some updates.

panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
Enter fullscreen mode Exit fullscreen mode

Changing click to transitionend and toggleOpen to toggleActive. A new function that we're about to write.

    function toggleActive(e) {
      if(e.propertyName.includes('flex')) {
        this.classList.toggle('open-active');
      }
    }
Enter fullscreen mode Exit fullscreen mode

This is the new function. Basically it needed to be written as an in statement to say if 'flex' was included, then it would toggle the open-active because of some weird browser differences dealing with flex.

Now time to remove the red border and to sub in some of my own photography for this project, maybe some of my own words!

Here it is live on my website!

Top comments (0)