How to Build a Responsive Navigation Bar using CSS Flexbox and JavaScript

How to Build a Responsive Navigation Bar using CSS Flexbox and JavaScript

Photo by KOBU Agency on Unsplash

This article was originally published at: itnext.io/how-to-build-a-responsive-navbar-..

In this article, we will create a fully responsive navigation bar from scratch using only flexbox and a little bit of JavaScript (for the toggle menu). So, I will assume you have basic knowledge of HTML, CSS, and JavaScript, that is, you should know the basic HTML tags and how to link the CSS and JavaScript files to HTML files.

I will be taking the mobile first approach for building the navigation bar. That is, we will first make the navigation bar for mobile devices and then for the desktop using media queries.

Getting started

Here’s the basic HTML for the layout:

<nav class="navbar">
    <a href="#" class="logo">logo</a>
    <ul class="main-nav" id="js-menu">
        <li>
            <a href="#" class="nav-links">Home</a>
        </li>
        <li>
            <a href="#" class="nav-links">Products</a>
        </li>
        <li>
            <a href="#" class="nav-links">About Us</a>
        </li>
        <li>
            <a href="#" class="nav-links">Contact Us</a>
        </li>
        <li>
            <a href="#" class="nav-links">Blog</a>
        </li>
    </ul>
</nav>

You can use any name for classes and Ids.

This is what we got after writing the above code, this isn’t much, but we will make it better by styling it using CSS.

Let's add some basic styling to make it look nice:

* {  
    box-sizing: border-box;  
    padding: 0;  
    margin: 0;  
}
body {  
    font-family: 'Josefin Sans', sans-serif;  
}
.navbar {  
    font-size: 18px;  
    background-image: linear-gradient(260deg, #2376ae 0%, #c16ecf   100%);  
    border: 1px solid rgba(0, 0, 0, 0.2);  
    padding-bottom: 10px;  
}
.main-nav {  
    list-style-type: none;  
}
.nav-links,  
.logo {  
    text-decoration: none;  
    color: rgba(255, 255, 255, 0.7);  
}

This certainly looks much better, I have stripped off any default browser specific padding and margin of every element using the universal selector (*), and set the box-sizing to border-box to make it easy to resize elements.

I have used ‘Josefin Sans’ font for the navigation bar and a linear-gradient for the background. You can choose your own fonts, colors, and background.

Now add some padding and margin to make it look better.

.main-nav li {  
    text-align: center;  
    margin: 15px auto;  
}
.logo {  
    display: inline-block;  
    font-size: 22px;  
    margin-top: 10px;  
    margin-left: 20px;  
}

The Toggle Button

It’s starting to look good. Now let’s add a little toggle button at the top right corner. For this, I am going to use Font Awesome icons.

This is what it looks like. Notice the little hamburger icon in the top left corner, this is looking weird. So let’s reposition and style it.

.navbar-toggle {  
    position: absolute;  
    top: 10px;  
    right: 20px;  
    cursor: pointer;   
    color: rgba(255,255,255,0.8);  
    font-size: 24px;  
}

The navbar for mobile devices is almost complete now. Let’s add a little bit of JavaScript to enable the toggle menu.

I have hidden the menu so that it’s not visible by default.

.main-nav {  
    list-style-type: none;  
    display: none;  
}

Now let’s add some JavaScript code to make it visible when someone clicks on the hamburger icon.

let mainNav = document.getElementById('js-menu');
let navBarToggle = document.getElementById('js-navbar-toggle');

navBarToggle.addEventListener('click', function () {  
    mainNav.classList.toggle('active');
});

This code toggles the active class on the menu list. So add the following code in the CSS file.

.active {  
  display: block;  
}

Nice and easy, with that our mobile part is over, now let’s move to the desktop part.

For Desktop:

for desktop, all we have to do is to change the flex-direction property to row and give a .navbar class a display property of flex.

@media screen and (min-width: 768px) {
    .navbar {  
        display: flex;  
        justify-content: space-between;  
        padding-bottom: 0;  
        height: 70px;  
        align-items: center;  
    }
    .main-nav {  
        display: flex;  
        margin-right: 30px;  
        flex-direction: row;  
        justify-content: flex-end;  
    }
    .main-nav li {  
        margin: 0;  
    }
    .nav-links {  
        margin-left: 40px;  
    }
    .logo {  
        margin-top: 0;  
    }
   .navbar-toggle {  
       display: none;  
    }
    .logo*:hover*,  
    .nav-links*:hover* {  
        color: rgba(255, 255, 255, 1);  
    }

Final Code:

<nav class="navbar">
   <span class="navbar-toggle" id="js-navbar-toggle">
   <i class="fas fa-bars"></i>
   </span>
   <a href="#" class="logo">logo</a>
   <ul class="main-nav" id="js-menu">
      <li>
         <a href="#" class="nav-links">Home</a>
      </li>
      <li>
         <a href="#" class="nav-links">Products</a>
      </li>
      <li>
         <a href="#" class="nav-links">About Us</a>
      </li>
      <li>
         <a href="#" class="nav-links">Contact Us</a>
      </li>
      <li>
         <a href="#" class="nav-links">Blog</a>
      </li>
   </ul>
</nav>
* {
   box-sizing: border-box;
   padding: 0;
   margin: 0;
}

body {
   font-family: 'Josefin Sans', sans-serif;
}

.navbar {
   font-size: 18px;
   background-image: linear-gradient(260deg, #2376ae 0%, #c16ecf 100%);
   border: 1px solid rgba(0, 0, 0, 0.2);
   padding-bottom: 10px;
}

.main-nav {
   list-style-type: none;
   display: none;
}

.nav-links,
.logo {
   text-decoration: none;
   color: rgba(255, 255, 255, 0.7);
}

.main-nav li {
   text-align: center;
   margin: 15px auto;
}

.logo {
   display: inline-block;
   font-size: 22px;
   margin-top: 10px;
   margin-left: 20px;
}

.navbar-toggle {
   position: absolute;
   top: 10px;
   right: 20px;
   cursor: pointer;
   color: rgba(255, 255, 255, 0.8);
   font-size: 24px;
}

.active {
   display: block;
}

@media screen and (min-width: 768px) {
   .navbar {
      display: flex;
      justify-content: space-between;
      padding-bottom: 0;
      height: 70px;
      align-items: center;
   }

   .main-nav {
      display: flex;
      margin-right: 30px;
      flex-direction: row;
      justify-content: flex-end;
   }

   .main-nav li {
      margin: 0;
   }

   .nav-links {
      margin-left: 40px;
   }

   .logo {
      margin-top: 0;
   }

   .navbar-toggle {
      display: none;
   }

   .logo:hover,
   .nav-links:hover {
      color: rgba(255, 255, 255, 1);
   }
}
let mainNav = document.getElementById('js-menu');
let navBarToggle = document.getElementById('js-navbar-toggle');

navBarToggle.addEventListener('click', function () {
   mainNav.classList.toggle('active');
});

Read more about Flexbox: