Building a vanilla JS navbar
Tags: codenewbie, webdev, tutorial, beginners
Published: 2020-10-11 16:05:28

In the [last iteration](https://dev.to/alvinqingxing/less-can-be-more-a-lot-more-1a5i) of my [personal website](https://alvinlim.me/), 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](https://dev-to-uploads.s3.amazonaws.com/i/faqroxuyulpel8thoynz.png)

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

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qvjpqkfivkndxecucegw.png)

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

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8snfd1set1euzs5zj75s.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/tmmvb5lvfq1sx9gn1qbz.png)

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](http://fontastic.me/) -- 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>
```
Once styled with CSS, the buttons wil look like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cb4lzziyjxg9o3061vqa.png)

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;
  ...
}
```
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>
```

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>
```

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>
```

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>
```

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](https://dev-to-uploads.s3.amazonaws.com/i/qhwntq8xvuwcrlkiayal.png)

If you're interested, the [source code](https://github.com/alvinqingxing/homepage) of my website is available on Github.