Responsive navigation menu with plain JavaScript 
Tags: javascript, css, html, webdev
Published: 2020-09-30 04:52:47

*Source code of this blog post could be found at:*
https://github.com/linhtch90/devto-responsive-nav-plain-js.git
*Showcase:*
https://linhtch90.github.io/devto-responsive-nav-plain-js/

## Introduction

Making a responsive navigation menu is a common task of frontend developers. The purpose of this blog post is to introduce necessary steps to build up a navigation menu which disappears at small screen **(less than 600px)** and get replaced by a hamburger button. 

**Main functions include:**

1. When you press the hamburger button: A side menu show up and the hamburger button is replace by a close button. 

2. When you press the close button or any menu item: The side bar collapses and the hamburger button show up again.

## Step 1

Let's make a simple webpage with html for demonstration purpose as below and save it as `./index.html` 

Please make sure that you also create folders for css and javascript files with similar names and paths as mentioned in the html file which is `./css/style.css` and `./js/hamburger.js`, respectively.

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- Styling -->
    <link rel="stylesheet" href="./css/style.css" />
    <!-- Google font: Open sans -->
    <link
      href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700;800&display=swap"
      rel="stylesheet"
    />
    <!-- Fontawesome -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
    />

    <title>
      Responsive navigation menu example
    </title>
  </head>
  <body>
    <div id="ham-button" class="hamburger-button" onclick="hamburgerMenu()">
      <i id="ham-icon" class="fas fa-bars"></i>
    </div>

    <div id="ham-menu" class="hamburger-menu">
      <ul>
        <li>
          <a href="#navigation"><div onclick="hamburgerMenu()">Home</div></a>
        </li>
        <li>
          <a href="#about"><div onclick="hamburgerMenu()">About</div></a>
        </li>
        <li>
          <a href="#projects"><div onclick="hamburgerMenu()">Projects</div></a>
        </li>
        <li>
          <a href="#blog"><div onclick="hamburgerMenu()">Blogs</div></a>
        </li>
        <li>
          <a href="#footer"><div onclick="hamburgerMenu()">Contact</div></a>
        </li>
      </ul>
    </div>
    <!-- Navigation bar -->
    <section id="navigation">
      <div class="container-dark">
        <nav class="navigation-bar">
          <ul>
            <li><a href="#navigation">Home</a></li>
            <li><a href="#about">About</a></li>
            <li><a href="#projects">Projects</a></li>
            <li><a href="#blog">Blogs</a></li>
            <li><a href="#footer">Contact</a></li>
          </ul>
        </nav>
      </div>
    </section>
    <!-- Home -->
    <section id="home">
      <div class="container-dark">
        <div class="container-home">Home</div>
      </div>
    </section>
    <!-- About -->
    <section id="about">
      <div class="container-light">
        <div class="container-about">About</div>
      </div>
    </section>

    <!-- Projects -->
    <section id="projects">
      <div class="container-dark">
        <div class="container-projects">Projects</div>
      </div>
    </section>

    <!-- Skills -->
    <section id="skills">
      <div class="container-light">
        <div class="container-skills">Skills</div>
      </div>
    </section>

    <!-- Timeline -->
    <section id="timeline">
      <div class="container-dark">
        <div class="container-timeline">Timeline</div>
      </div>
    </section>

    <!-- Blog -->
    <section id="blog">
      <div class="container-light">
        <div class="container-blog">Blog</div>
      </div>
    </section>

    <!-- Footer -->
    <section id="footer">
      <footer>
        <div class="container-dark">
          <div class="container-footer">
            <div class="footer-icon-list">
              <i class="fab fa-twitter footer-icon"></i>
              <i class="fab fa-linkedin footer-icon"></i>
              <i class="fab fa-github footer-icon"></i>
              <i class="fab fa-dev footer-icon"></i>
              <i class="fab fa-instagram footer-icon"></i>
            </div>
          </div>
        </div>
      </footer>
    </section>

    <script type="text/javascript" src="./js/hamburger.js"></script>
  </body>
</html>
```

## Step 2

Let's make our html look better and responsible by adding some CSS to `./css/style.css`

```css
html {
  scroll-behavior: smooth;
  overflow-x: hidden;
}

body {
  font-family: "Open Sans", sans-serif;
  margin: 0px;
  background-color: rgb(51, 44, 56);
  box-sizing: border-box;
  overflow-x: hidden;
}

h1 {
  padding: 0;
  margin: 0;
}

h2 {
  margin: 0;
  padding: 0;
}

p {
  margin: 0;
  padding: 0;
}

.container-dark {
  display: flex;
  width: 100%;
  justify-content: center;
}

.container-light {
  display: flex;
  width: 100%;
  justify-content: center;
  background-color: whitesmoke;
}

/* Hamburger button */

.hamburger-button {
  display: none;
}

.hamburger-menu {
  display: none;
}

/* Navigation bar */

.navigation-bar {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 75%;
  height: 10vh;
}

.navigation-bar > ul {
  display: flex;
  width: 100%;
  list-style-type: none;
  justify-content: space-between;
  flex-direction: row;
  padding: 0;
}

.navigation-bar > ul > li {
  width: fit-content;
}

.navigation-bar > ul > li > a {
  text-decoration: none;
  color: whitesmoke;
  font-weight: 700;
  letter-spacing: 0.2rem;
}

.navigation-bar > ul > li > a:hover {
  color: green;
  transition: 0.75s;
  cursor: pointer;
}

/* Home section */

.container-home {
  display: flex;
  width: 75%;
  height: 90vh;
  justify-content: center;
  align-items: center;
  font-size: 2rem;
  font-weight: 700;
  color: green;
}

/* About section */

.container-about {
  display: flex;
  width: 75%;
  height: 20rem;
  background-color: whitesmoke;
  justify-content: center;
  align-items: center;
  font-size: 2rem;
  font-weight: 700;
  color: green;
}

/* Projects */

.container-projects {
  display: flex;
  width: 75%;
  height: 20rem;
  justify-content: center;
  align-items: center;
  font-size: 2rem;
  font-weight: 700;
  color: green;
}

/* Skills */

.container-skills {
  display: flex;
  width: 75%;
  height: 20rem;
  justify-content: center;
  align-items: center;
  font-size: 2rem;
  font-weight: 700;
  color: green;
}

/* Timeline */

.container-timeline {
  display: flex;
  width: 75%;
  height: 20rem;
  justify-content: center;
  align-items: center;
  font-size: 2rem;
  font-weight: 700;
  color: green;
}

/* Blog */

.container-blog {
  display: flex;
  width: 75%;
  height: 20rem;
  justify-content: center;
  align-items: center;
  font-size: 2rem;
  font-weight: 700;
  color: green;
}

/* Footer */

.container-footer {
  display: flex;
  width: 75%;
  height: 20rem;
  justify-content: center;
  align-items: center;
  font-size: 2rem;
  font-weight: 700;
  color: green;
}

.footer-icon-list {
  font-size: 1.5rem;
  color: whitesmoke;
  margin-top: 2rem;
  margin-bottom: 2rem;
  letter-spacing: 1rem;
}

.footer-icon:hover {
  color: green;
  cursor: pointer;
  transition: 0.75s;
}

/* Responsive  */

/* For mobile large */

@media only screen and (max-width: 600px) {
  .navigation-bar {
    visibility: hidden;
  }

  li a.icon {
    visibility: visible;
  }

  /* Home */

  .container-home {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 20rem;
    justify-content: center;
    align-items: center;
    margin-top: 0;
    padding-top: 0;
  }

  /* About section */

  .container-about {
    display: flex;
    height: auto;
    width: 75%;
    height: 20rem;
    background-color: whitesmoke;
  }

  /* Projects */

  .container-projects {
    width: 100%;
  }

  /* Skills */

  .container-skills {
    width: 100%;
  }

  /* Timeline */

  .container-timeline {
    width: 60%;
  }

  /* Blog */

  .container-blog {
    width: 100%;
  }

  /* Footer */

  .container-footer {
    width: 100%;
  }

  /* Hamburger button */
  .hamburger-button {
    display: block;
    font-size: 2rem;
    color: green;
    background-color: transparent;
    border: none;
    position: fixed;
    left: 1rem;
    top: 1rem;
    z-index: 30;
  }

  .hamburger-menu {
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100vh;
    padding: 0;
    position: fixed;
    left: 0;
    top: 0;
    z-index: 20;
    background-color: rgb(51, 44, 56);
  }

  .hamburger-menu > ul {
    display: flex;
    flex-direction: column;
    width: 100%;
    list-style-type: none;
    justify-content: center;
    align-items: center;
    padding: 0;
  }

  .hamburger-menu > ul > li {
    width: fit-content;
    margin: 1.5rem;
  }

  .hamburger-menu > ul > li > a {
    text-decoration: none;
    font-size: 2rem;
    color: whitesmoke;
    font-weight: 700;
    letter-spacing: 0.2rem;
  }

  .hamburger-menu > ul > li > a:hover {
    color: green;
    transition: 0.75s;
    cursor: pointer;
  }
}

```

## Step 3

Add the below code to `./js/hamburger.js`

This is the code for handling the collapsible menu bar as well as toggling the hamburger button and close button.

```javascript
function hamburgerMenu() {
  // Toggle the side menu
  let hamburgerMenu = document.querySelector(".hamburger-menu");
  let menuStyle = getComputedStyle(hamburgerMenu);

  if (menuStyle.display == "none") {
    document.getElementById("ham-menu").style.display = "flex";
  } else {
    document.getElementById("ham-menu").style.display = "none";
  }

  // Exchange hamburger icon and close icon
  let hamburgerIcon = document.querySelector("#ham-icon");
  if (hamburgerIcon.classList.contains("fa-bars")) {
    hamburgerIcon.classList.replace("fa-bars", "fa-times-circle");
    return;
  } else {
    hamburgerIcon.classList.replace("fa-times-circle", "fa-bars");
    return;
  }
}
```

# DONE!

Now you can open `./index.html` file with your web browser and inspect the responsive navigation menu that we have just built.

Happy coding!