DEV Community

loading...
Cover image for Building a vanilla JS navbar

Building a vanilla JS navbar

alvinqingxing profile image Alvin Lim ・3 min read

In the last iteration of my personal website, I removed all JavaScript and used HTML5's details/summary elements to selectively show or hide the different sections of my website.

While this led my website to achieve a 100% Lighthouse performance score, I didn't like the resulting appearance. Hence I decided to bring back just enough JavaScript to build a simple navbar to accomplish that same task.

This is how I wanted my website to look. When you first land on my website -- and if you click the "Hello" button in the navbar -- you will be presented with the "About" section:

Alt Text

If you click the "Code" button, you will be presented with the Coding Projects section of the page:

Alt Text

And finally, if you click the "Contact" button, you will be presented with the contact form:

Alt Text

The key thing to note is that these three sections are not three separate HTML files but are instead three sections of one HTML file. JavaScript is used to hide two of these three sections at any one time, creating the illusion that there are three separate files. This can be seen when JavaScript is disabled. In this situation, all 3 sections are displayed:

Alt Text

To achieve this look, I first identified the About, Coding Projects, and Contact Form sections with the appropriate id tags in the HTML: <article id="about">, <article id="code">, and <article id="contact">.

In the navbar, each button -- which is just an anchor element with text and an icon from Fontastic -- has its own unique id:

<nav>
  <a id="nav-about">#Hello <i class="icon-smile-o"></i></a>
  <a id="nav-code">#Code <i class="icon-codepen"></i></a>
  <a id="nav-contact">#Contact <i class="icon-pencil"></i></a>
</nav>
Enter fullscreen mode Exit fullscreen mode

Once styled with CSS, the buttons wil look like this:

Alt Text

With these ids in place, we can now use JavaScript to pair each button element in the navbar with its corresponding article element in the HTML, and create event listeners to change the appearance of the website when the different buttons are clicked.

First, the navbar. Since the navbar uses JavaScript to control the appearance of the website, it is useless if JavaScript is -- for whatever reason -- disabled on the browser. In this situation, I do not want the navbar to appear. Hence in CSS the navbar is hidden by default:

nav {
  display: none;
  ...
}
Enter fullscreen mode Exit fullscreen mode

If JavaScript is working in the browser, the following script in the HTML will activate the navbar. The script will also display the "About" section and hide the "Code" and "Contact" sections, giving us the desired default appearance of the website:

 <script>
    document.querySelector("nav").style.display = "flex";
    document.getElementById("about").style.display = "block";
    document.getElementById("code").style.display = "none";
    document.getElementById("contact").style.display = "none";
    ...
  </script>
Enter fullscreen mode Exit fullscreen mode

Now the event listeners can be added. When the "Hello" button (with the nav-about id) is clicked, the "About" section should be shown while the "Code" and "Contact" sections remain hidden:

 <script>
    ...
    document.getElementById("nav-about").addEventListener("click", function () {
      document.getElementById("about").style.display = "block";
      document.getElementById("code").style.display = "none";
      document.getElementById("contact").style.display = "none";
    });
   ...
  </script>
Enter fullscreen mode Exit fullscreen mode

When the "Code" button (id: nav-code) is clicked, the "Code" section should be shown and the "About" and "Contact" sections hidden:

 <script>
    ...
    document.getElementById("nav-code").addEventListener("click", function () {
      document.getElementById("about").style.display = "none";
      document.getElementById("code").style.display = "block";
      document.getElementById("contact").style.display = "none";
    });
    ...
  </script>
Enter fullscreen mode Exit fullscreen mode

Finally, when the "Contact" button (id: nav-contact) is clicked, the "Contact" section should appear with the other two sections remaining hidden.

 <script>
    ...
    document.getElementById("nav-contact").addEventListener("click", function () {
      document.getElementById("about").style.display = "none";
      document.getElementById("code").style.display = "none";
      document.getElementById("contact").style.display = "block";
    });
  </script>
Enter fullscreen mode Exit fullscreen mode

And that's it! With these event listeners in place, the buttons are now functional. With the reintroduction of JavaScript to my website, I had concerns about the impact on performance, but a Lighthouse audit allayed my fears:

Alt Text

If you're interested, the source code of my website is available on Github.

Discussion (0)

pic
Editor guide