How to create responsive navbar using css and JavaScript

Last Updated on Sep 06, 2023

responsive-navbar

In this blog we will create a responsive navigation bar using HTML, CSS, and a little bit of JavaScript.

We will create a top navigation that turns to offcanvas in narrow screen devices. Offcanvas is a sidebar that can be showed and hidden by a button using JavaScript.

In this tutorial I will use 4 files named index.html, style.css, script.js and an image logo named logo.svg. In addition I will use font awesome v5.15.4 to use the hamburger menu icon. You can create your own fontawesome kit but you are free to use my kit.

  1. Get Started with HTML

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link  rel="stylesheet" href="style.css">
        <title>Responsive Navbar</title>
        <!-- My Font Awesome Kit -->
        <script src="https://kit.fontawesome.com/16c4a07abd.js" crossorigin="anonymous"></script>
      </head>
      <body>
        <nav>
          <div class="navbar" id="navbar">
            <button class="navbar-close" id="navbar-close">&times;</button>
            <a href="#home" class="navbar-link"><img src="logo.svg" class="navbar-logo" alt="home"></a>
            <a href="#about" class="navbar-link">About</a>
            <a href="#contact" class="navbar-link">Contact</a>
            <a href="#privacy-policy" class="navbar-link">Privacy Policy</a>
            <a href="#disclaimer" class="navbar-link">Disclaimer</a>
          </div>
          <div class="navbar-small-screen">
            <button id="navbar-open" class="navbar-open"><i class="fas fa-bars"></i></button>
            <a href="#home" class="navbar-link"><img src="logo.svg" class="navbar-logo" alt="home"></a>
          </div>
        </nav>
        <div class="content">
          Content goes here...
        </div>
        <script src="script.js"></script>
      </body>
    </html>						
    

    In our <nav> we have 2 <div>.

    The first <div> is our topbar on wide screens and sidebar on narrow screens. It contains the navigation links and a close <button> that only showed on narrow screen.

    The second <div> will be our topbar on narrow screen devices. It contains an image logo and a <button> to show our sidebar menu. It will not be not visible on wide screens.
    Take note that the navigation links for homepage is the image logo instead of the 'home' text.

    Now let's implement everything I said with CSS and JavaScript.

  2. Add CSS

    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
      font-family: sans-serif;
    }
    .navbar {
      display: flex;
      justify-content: space-evenly;
      align-items: center;
      background: blue;
    }
    .navbar-logo {
      height: 50px;
      width: auto;
    }
    .navbar-link {
      padding: 10px 0;
      text-decoration: none;
      color: white;
      font-size: 18px;
      font-weight: 700;
    }
    .navbar-link:hover {
      color: orange;
    }
    .navbar-small-screen, .navbar-close {
      display: none;
    }
    .content {
      padding: 20px;
    }
    
    @media screen and (max-width: 992px) {
      .navbar {
        flex-direction: column;
        justify-content: flex-start;
        align-items: flex-start;
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        width: 0px;
        visibility: hidden;
        overflow: hidden;
        transition: width .5s, visibility .5s;
      }
      .navbar-link {
        padding: 10px;
      }
      .navbar .navbar-logo {
        display: none;
      }
      .navbar-small-screen {
        display: flex;
        justify-content: space-between;
        background: blue;
      }
      .navbar-open, .navbar-close {
        background: none;
        border: none;
        cursor: pointer;
      }
      .navbar-open {
        padding: 15px;
        font-size: 20px;
        color: white;
      }
      .navbar-close {
        display: block;
        position: absolute;
        top: 0;
        right: 0;
        padding: 10px;
        font-size: 40px;
        color: hsl(0, 0%, 80%);
      }
      .navbar-close:hover {
        color: red;
      }
      .show-menu {
        visibility: visible;
        width: 270px;
      }
    }
    

    Our .navbar uses Flexbox. It uses flex-direction: row on wide screens to make the navigation links side by side and flex-direction: column on narrow screens to make it on top of each other with the help of media query. Take note that the default value of flex-direction is row so we don't need to set it.

    To turn our topbar to sidebar on narrow devices we uses position: fixed, top: 0, left: 0, and set our width to our preferred value.

    You might notice that I didn't used display: none to .navbar in media query to hide the sidebar, that is because transition will not work and we will animate the opening and closing of sidebar menu using width, visibility, and transition. We also used overflow: hidden because there is a slight delay in hiding the navigation links when closing the sidebar menu.

    In the next section we will use JavaScript to implement the opening and closing of sidebar menu by toggling the class .show-menu

  3. Add JavaScript

    const openMenuBtn = document.getElementById('navbar-open');
    const closeMenuBtn = document.getElementById('navbar-close');
    
    window.addEventListener('click', handleWindowClick);
    openMenuBtn.addEventListener('click', handleMenu);
    closeMenuBtn.addEventListener('click', handleMenu);
    
    function handleMenu() {
      const navbar = document.getElementById('navbar');
      navbar.classList.toggle('show-menu');
    }
    
    function handleWindowClick(e) {
      const navbar = document.getElementById('navbar');
      if(!navbar.contains(e.target) && !openMenuBtn.contains(e.target)) {
        navbar.classList.remove('show-menu');
      }
    }
    

    In our JavaScript we have 2 functions named handleMenu and handleWindowClick.The handleMenu opens and closes the sidebar when the openMenuBtn and closeMenuBtn is clicked. The handleWindowClick closes the sidebar when clicked outside of sidebar with the exception of the openMenuBtn.

Conclusion

Today you just learned how to create a responsive navigation links. However this is just one way to do it. Make sure that you understand every line of code in this post including those I didn't explain. If you have any questions for me don't hesitate to contact me.

© John Michael Balbarona