Build a smart navigation using vanilla JavaScript

One step further from the "sticky navigation bar".

Build a smart navigation using vanilla JavaScript

We have all seen sticky navigation bar which stick to the top of the website so that user don't have to scroll all the way to navigate through the website. But this type of navigation bar (referred as "nav bar from now on") takes up space on the viewport and takes away user's attention from the things that are more important on the website and thus leads to an unpleasant user experience.

Therefore, an additional functionality is added to the sticky navigation which shows the nav bar only when the user is scrolling up (which usually means that user wants to navigate to some other part of the website) and when user is scrolling down it is hidden so that the navigation doesn't take unintended attention.

Steps to achieve a smart navigation:-

  1. Create a nice nav bar.
  2. Create sticky functionality for the nav bar.
  3. Get the scrolling position of the web page.
  4. If web page is scrolled up by the user, add the sticky functionality.
  5. Otherwise if the web page is scrolled down by the user remove the sticky functionality.
  6. An additional step for better appearance.

Code to implement the above mentioned steps:-

1. Create a nice nav bar

To create a nav bar, I defined a span element for the logo and a un-ordered list for the navigation list and wrapped all of it in a header which is the most common technique to create a nav bar.

Note: Nav bar usually contains links but this code is not really focusing on the functionality of nav bar but the appearance and that's why I used simple text.

<header class="header">
  <span class="label">Label</span>
  <nav class="nav-bar">
    <ul class="nav-list">
      <li>Home</li>
      <li>About</li>
      <li>Pricing</li>
      <li>Contact</li>
    </ul>
  </nav>
</header>

2. Create the sticky functionality for the nav bar

To do this, I defined all the CSS properties I want to be applied to the nav bar under class name ".header".

.sticky .header {
  position: fixed;
  height: 5rem;
  top: 0;
  bottom: 0;
  width: 100%;
  background-color: rgba(255, 255, 255, 0.985);
  box-shadow: 0 1.2rem 3.2rem rgba(0, 0, 0, 0.03);
}

This "sticky" class is added to the body when user scrolls up and therefore, we say that the element containing "header" class (

element) defined inside of the element containing the "sticky" class( element) will now stick to the top of the web page.

Now one more thing you should be aware of is that we are taking the nav bar out of the page's normal flow by making doing "position: fixed". And when we do that, there is a chance that it might mess up the spacing in our webpage. To fix that we will add a margin-top to the very first element of our webpage with the same value as the height of our nav bar which (here it is 5rem). We add 5rem of margin to the top to the first element in the body (section-1 here) if and when the body has class "sticky".

.sticky .section-1 {
  margin-top: 5rem;
}

3. Get the scrolling position of the web page

Now, JavaScript comes in the story.

lastScrollTop = 0;
window.addEventListener("scroll", function() {
var currentPosition = window.pageYOffset || window.scrollY;
});

We define the lastScrollTop = 0 for the initial scrolling position which is 0 which will be replaced in future. Now, as user scrolls the page , we get the current position (number of pixels scrolled vertically).

4. If web page is scrolled up by the user, add the sticky functionality

We first need to check if user has scrolled up or not. This code will be appended in the "scroll" event handler.

//scrolled up
  if(currentPosition < lastScrollTop) {
    if(!document.body.classList.contains("sticky")) {
    document.body.classList.add("sticky");
    }

If the currentPosition < lastScrollTop then the page is scrolled up. In this case, if the body doesn't contain the "sticky" class, we add it.

5. Otherwise if the web page is scrolled down by the user remove the sticky functionality

This code will be appended in the "scroll" event handler.

if(currentPosition > lastScrollTop) {
    if(document.body.classList.contains("sticky")) {
    document.body.classList.remove("sticky");
    }
  }

Now, if user scrolled down we will remove the class "sticky" form the body because we don't want the nav bar when user is scrolling down.

6. An additional step for better appearance

After only writing this code, there will be a problem. When user scrolls all the way up to the page our nav bar will be the one with the sticky functionality because the last event performed was the scroll up and therefore, body will be containing the "sticky" class. But we don't want that, what we want is that when user reaches the top of the web page after scrolling through the page, the header should be embedded in the page as usual and not be fixed at a particular position.

To do that we write:-

if(currentPosition == 0) { if(document.body.classList.contains("sticky")) {
    document.body.classList.remove("sticky");
    }
  }

If the currentPosition is zero, it means user reached the top of the web page so now remove the "sticky" class from the body. This code will be appended in the "scroll" event handler.

Therefore, after applying steps 3, 4, 5 and 6 our JavaScript code will look something like this:-

lastScrollTop = 0;
window.addEventListener("scroll", function() {
  var currentPosition = window.pageYOffset || window.scrollY;

//   Top of the page
  if(currentPosition == 0) { if(document.body.classList.contains("sticky")) {
    document.body.classList.remove("sticky");
    }
  }

  //Scrolled down
  else if(currentPosition > lastScrollTop) {
    if(document.body.classList.contains("sticky")) {
    document.body.classList.remove("sticky");
    }
  }

  //scrolled up
  else if(currentPosition < lastScrollTop) {
    if(!document.body.classList.contains("sticky")) {
    document.body.classList.add("sticky");
    }
  }

  //update last scrolled position
  lastScrollTop = currentPosition; 
});

Also, carefully examine the last line after comment "update last scrolled position". We are storing the the currentPosition is the lastScrollTop because the next time user scrolls the page and this function is called the last scrolled position would be the current position of the previous scroll.

Now go are ready to create your own Smart Navigation Bar so go ahead and code!

You can see my Smart Navigation Bar here

Have questions? Post them in comments. I will reply within 48 hours.

Thanks for reading ❤