Fantastic stripe-like follow along nav with CSS and Javascript explained

Another great Javascript example from WesBos whom I really enjoy his work named a follow along nav example. He uses stripe-like follow along nav which uses a fantastic technique to have a beautiful hover over effect on list items. I will not change the example and created a pen to explain it.

Follow along nav example

I have used the same content as well so you can checkout his work and learn more from his excellent courses. Here is the pen I have created:

Basically it is a menu which when you hover over each tab and you follow along hovering over other tabs, the white background behind tab’s dropdown menu follows your movement.

Therefor you always see the white background moving along with a nice transition. Also it changes its width and heigh according to the current hovered over dropdown. The idea is from stipe‘s navigation bar.

stripe nav

The HTML

We have an unordered list with a link and a dropdown menu inside each list item. Also we have a title on the top which is there for a purpose that I explain later along coding it.

But the most important part is the background container which is a div inside the nav:

<div class="dropdownBackground">
    <span class="arrow"></span>
</div>

It has an absolute positioning and a width and height. But important CSS code for this background is its opacity. We will change that opacity which is zero to 1 once we hover over an item.

Follow along nav Javascript and CSS

We better check what elements we need to work on. Firstly we need the list items. Then the background div and finally the nav itself which I explain why later.

// Select all list items using querySelectorAll
const triggers = document.querySelectorAll('.cool > li');
// Select only the background using querySelector
const background  = document.querySelector('.dropdownBackground');
// Select the nav
const nav  = document.querySelector('.top');

Next step is to know what we need to do. We need to show the background behind the dropdown once we hover over each list item. Also when we hover off of that item and over over another item the background should follow along. That is why it is called follow along nav.

Therefor we need two functions for entering the item and leaving it. So we better create event listeners for each time items being hovered using arrow functions:

triggers.forEach(trigger => trigger.addEventListener('mouseenter', handleEnter));

  triggers.forEach(trigger => trigger.addEventListener('mouseleave', handleLeave));

CSS classes for both functions

We need to add the opacity to the background once mouse enters it:

.dropdownBackground.open {
    opacity: 1;
}

We also need two more classes for the dropdown. The dropdown is hidden with display: none but it also has opacity: 0. The reason is once we hover over a list item we first display the dropdown meaning display: block it. Then after 150ms (setTimeout) we change the opacity to 1 so that we have that nice transitioned effect we see once that item is active:

.trigger-enter .dropdown {
    display: block;
}
.trigger-enter-active .dropdown {
    opacity: 1;
}

So far we will have the enter function set up like this:

function handleEnter() {
 // add trigger-enter class to dropdown
    this.classList.add('trigger-enter');
// create a timeout which checks of the classList contains the trigger-enter. If true then it moves on and adds trigger-enter-active to the classList
    setTimeout(() => this.classList.contains('trigger-enter') && this.classList.add('trigger-enter-active'), 150);
// show the background
    background.classList.add('open');
}

Int he setTimeout function we have a && condition. What it does is it checks the first condition which is if the item’s dropdown has got display: block or not.

If not it does not go on and will not make the opacity 1 meaning it does not add class trigger-enter-active to dropdown calssList until you actually hover over the item. Because you might hover over menu items even quicker than 150ms and that way it cannot properly add the active class on time before it is been removed in mouseleave event and that is not correct. So we add this little check to make sure the active class is not been added until you are on one item hovering.

Here we remove classes in our mouseleave event handler:

 function handleLeave() {
    this.classList.remove('trigger-enter', 'trigger-enter-active');
    background.classList.remove('open');
  }

Coordinates

Until this step we have shown the background and the dropdown. But the background is not in the correct position. You will see it on the top left when you hover over each item:

background is on top left once hover over items

As a result for a follow along nav to work as its name suggests we need to calculate the coordinates of each item and position the background there accordingly. Also remember I mentioned about the title “cool” on the top.

We need to calculate coordinates based on the distance from the top. If we only had the navbar in the page we could just calculate the dropdown cords(coordinates)  itself. But we might have a title or something else there so we better calculate the navbar cords as well and reduce it from dropdown’s left and right cords:

// We need to select the selected dropdown here   
const dropdown = this.querySelector('.dropdown');
// calculate its cords
const dropdownCoords = dropdown.getBoundingClientRect();
// calculate nav's cords
const navCoords = nav.getBoundingClientRect();
// finally this will be the cords for the background of each dropdown
const coords = {
      height: dropdownCoords.height,
      width: dropdownCoords.width,
      top: dropdownCoords.top - navCoords.top,
      left: dropdownCoords.left - navCoords.left
};

After we calculated the cords for both nav and dropdown we assign it to the background cords as below:

// assign the width and heigth using <a href="https://www.nikpro.com.au/template-literals-in-js6-explained/">template literals</a>
background.style.setProperty('width', ${coords.width}px);
background.style.setProperty('height', ${coords.height}px);
// the left and right cords should be assigned to tranform prperty in CSS
background.style.setProperty('transform', translate(${coords.left}px, ${coords.top}px));

final nav

The final nav

Finally we are done. We have explained a follow along nav that is a fantastic example of a modern hover over effect based on Javascript and CSS.

Thank you for reading.

© 2019
Azadeh Faramarzi

This site is created and maintined by Azadeh Faramarzi , A passionate developer, sport and code lover who loves to share and write when she has some time.