Make a Navbar with toggle Menu using just CSS and Vanilla JavaScript

NOTICE: There is an improved version of this same article to. Click here to see it

With the deluge of CSS front-end frameworks available nowadays making a toggle navbar has become so easy and less painful. But how do you make a toggle navigation without Jquery or CSS frameworks using just vanilla JS?

In this article I'll explain how to make a responsive navbar that adapt to various screen size using media query. And pure JS for the toggle function.

This is what we'll be building

The setup

Let's begin with a simple HTML markup

From the markup above I'm pretty sure you already have a clue where we are heading, We're going to hide one set of menu and show the other depending on the screen size with the help of the CSS property(Media Query)

If you haven't noticed, in the navbar there is an i tag inside an anchor tag, that's actually the icon. It's a fontawesome icon.

What next?

We're done with our HTML markup now let's get started with the CSS part. We'll start with the nav tag.

  
    nav{
        width: 100%;
        height: 50px;
        background: #fff;
        box-shadow: 0 4px 4px -1px #eaeded;
        padding-bottom: 20px;
    }
  

Next the a tag with the class of logo

  
    nav .logo{
        position: absolute;
        left: 0;
        top: 0;
        padding: 30px;
        text-decoration: none;
        color: #37a000;
        font-size: 1.3rem;
        text-transform: uppercase;
        transition: all ease-in-out .2s;
    }
  

The ul and li inside the nav tag Note: this styles doesn't apply to mobile devices, because we're going to show this specific ul & lis only on large devices.

  
    nav ul{
        margin-right: 20%;
          float: right;
    }
    nav ul li{
        display: block;
        padding: 20px 20px 0 20px;
        list-style: none;
    }
  

Styling the a tags

  
    nav li > a{
        color: #333;
        text-decoration: none;
        font-size: 1.1rem;
        transition: all ease-out .2s;
    }
    nav li > a:hover{
        color: #37a000;
    }
  

We're done with the navbar for large screen devices

Now let's jump into the styles for mobile devices


    .mobile-nav{
        position: absolute; /* fixed or absolute should work*/
        top: 0;
        left: 0;
        height: 100%;
        overflow: hidden;
        background: #F8F9F9;
        width: 0;
        z-index: 10;
        transition: all ease-in-out .2s;
    }

    .mobile-nav li{
        display: block;
        padding: 20px 0;
        list-style: none;
    }

    .mobile-nav li a{
        text-decoration: none;
        font-size: 1.2rem;
        color: #333;
        font-weight: 400;
    }


Remember that icon we talked about? Yah those 3 horizontal bars icon. take a peek again it's inside an a tag with the class of toggle. Let's style it.

  
    .toggle{
        float: left;
        padding: 15px 0 10px 20px;
        transition: all ease-in-out .2s;
    }
    .toggle .fa-bars{
        font-size: 1.5rem;
        color: #17202A;
    }

  

Hey! we're almost there. Now let's set some styles depending on the devices. For device screen less than 800px we want to apply these styles.

  
    @media (max-width:800px){
        nav ul li{
        display: none;
        }

        nav .logo{
            position: absolute;
            left: 50%;
            transform: translateX(-50%);
        }
    }
  

And for device screen greater than 800px we want these styles.

  

    @media (min-width:800px){
        .mobile-nav{
        display: none;
        }
        .toggle{
            display: none;
        }
    }

  

Finally

Tada!!!

But wait, there's more. The JavaScript part

We start by delaring variables, we want to get the elements by thier classnames and assign each of the to a variable.

  
    const toggleIcon = document.querySelector('.toggle');

    const logo = document.querySelector('.logo');

    const mobileNav = document.querySelector('.mobile-nav');
  

The 3 variables we just assigned: toggleIcon: the three horizontal bars icon , logo: the site logo mobileNav: the mobile navbar

Before we go any further let's define some CSS classes. these classes will be toggled when the icon menu is clicked.

  
    .toggle-open{
        width: 70%;
    }
    .margin-toggle{
        margin-left: 70%;
    }
    .logo-opacity{
        opacity: 0;
    }
  

Adding a click event to the bars icon. But what do we want to happened when the icon is clicked?

1. toggle between the .logo-opacity class to make the logo disappear or appear so it does look like the .mobile-nav class is passing througt the logo.

2. The .mobile-nav class by default has a width of 0%, when the icon is clicked we want to toggle between the .toggle-open class we created above which has a width of 70%.

3. we want the bars icon to move 70% right using the .margin-toggle class.

Note: The class .toggle-open and .margin-toggle we want a 100ms delay before there are applied.

This is what it looks like

  
      toggleIcon.addEventListener('click', function(){

      logo.classList.toggle('logo-opacity');

          setTimeout(() => {
              mobileNav.classList.toggle('toggle-open');
              toggleIcon.classList.toggle('margin-toggle');
          }, 100);

  });

  

Here you go, that's how to make a responsive navbar using just vanilla JS and pure CSS.