Sometimes all you want is to create a simple responsive sidebar menu that displays the navigation links on smaller screens, e.g. mobile.

But you don’t want the overhead of heavy frameworks like Bootstrap, right?

The best way of going about is to create a responsive sidebar menu from scratch with minimal markup. This quick tutorial will show you how.

And here’s a preview of what we’ll build:

We’ll be using simple HTML, CSS, SVG (for the hamburger icon) and 4 lines of Javascript.

Disclaimer: I’m a self-taught coder and if you have some ideas or suggestions on how to make this better, please let me know.

Let’s start, shall we?

Marking Up The Horizontal Menu

We’ll be starting out by creating an empty index.html file and an empty style.css for our styling. You can use whatever name you like.

You can use your notepad, Atom or any other code editor of your choice. Although it sounds like overkill for a small project like this, I’ll be using Visual Studio Code.

Ready? Let’s start by creating the basic HTML structure in our index.html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="style.css" />
    <title>Responsive Side Nav</title>
  </head>
  <body>
    <nav id="main-nav">
      <span class="main-nav__toggle">
        <a href="#" onclick="openSideMenu()">
          <svg width="30" height="30">
            <path d="M0,5 30,5" stroke="#fff" stroke-width="5" />
            <path d="M0,14 30,14" stroke="#fff" stroke-width="5" />
            <path d="M0,23 30,23" stroke="#fff" stroke-width="5" />
          </svg>
        </a>
      </span>
      <ul class="main-nav__links">
        <li><a href="#home">Home</a></li>
        <li><a href="#about">About</a></li>
        <li><a href="#blog">Blog</a></li>
        <li><a href="#contact">Contact</a></li>
      </ul>
    </nav>
  </body>

I started by creating the nav element which we’ll use for the horizontal navigation. Within here, I’m nesting a new <span> element. This will ‘hold’ our hamburger style link.

You probably noticed the I added an onclick event on line 13. This one calls the function openSideMenu() which we’ll create later. This one, you might have guessed, will be responsible for opening the side menu.

Adding A Hamburger Toggle

I decided to use a hamburger menu for our responsive website to reduce clutter and save space. When the viewer’s screen size reaches a certain point (568px in this example) the hamburger icon will replace the links.

There are various different methods of creating the hamburger menu. You could use the Font Awesome library, basic CSS, or Scalable Vector Graphic (SVG). I decided to try something new and opted for the latter.

Basically, I’m using SVG to create three white lines with a fixed width & color to create the Hamburger toggle.

The d attribute defines the path we want to draw. The M stands for MoveTo. You can imagine this as picking up a pen, drawing a line and setting it down somewhere else. The numbers represent the x & y coordinates.

Next up, let’s add the markup for our responsive sidebar menu.

Adding Markup For The Sidebar Menu

Next up, adding the main part with the sidebar. Because the sidebar menu is really the main part of this little tutorial, I added the sidebar within the main tag.

In hindsight, some research on MDN suggests the following:

The content of a <main> element should be unique to the document or section the element contains. Content that is repeated across a set of documents or document sections such as sidebars, navigation links, copyright information, site logos, and search forms should not be included unless the search form is the main function of the page.

Ultimately, it’s up to you.

Still with me?

Our main tag includes a <div> with the id main__content which will hold, well, the main content. I bet you could have guessed that.

The other <div> includes an empty <a href…> attribute‘ and a class I called “btn-close“. This will be used to display little ‘x‘ that allows users to close the sidebar.

<main id="main">
  <div id="main__content">
    <h1>Responsive Side Nav</h1>
    <p>Reduce screen size to < 568px to see side nav toggle</p>
  </div>
  <div id="side-nav">
    <a href="#" class="btn-close" onclick="closeSideMenu()">×</a>
    <a href="#home">Home</a>
    <a href="#about">About</a>
    <a href="#blog">Blog</a>
    <a href="#contact">Contact</a>
  </div>
</main>

Opening & Closing The Sidebar Menu With Javascript

We can use Javascript to open and close the side menu while also pushing the main content to the right. Let’s face it, we don’t want the sidebar menu to overlap our main content, do we?

Remember the onclick handler we’ve added to our markup? We now need to create the function. In order to do this, simply add a script tag right above the closing body within your index.html.

<script>
  function openSideMenu() {
    document.getElementById("side-nav").style.width = "250px"
    document.getElementById("main__content").style.marginLeft="250px"
  }
</script>

How it will work is pretty simple and straightforward. Upon clicking the hamburger toggle, the function openSideMenu() will be called. This function changes the width of the sidebar navigation to 250px.

Note: Of course, we need to set the original width to 0 and we’ll do this in our style.css in just a moment.

At the same time, we’re adding a margin of 250px to the left of the main content. To close the side menu, we’ve added another onclick event to the little x here:

<a href="#" class="btn-close" onclick="closeSideMenu()">×</a>

The closeSideMenu() function will do the opposite. Reducing the width of both elements from 250px to 0.

function closeSideMenu() {
    document.getElementById("side-nav").style.width = "0"
    document.getElementById("main__content").style.marginLeft = "0"
  }

Simple enough.

For your reference, the entire index.html should now look like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="style.css" />
    <title>Responsive Side Nav</title>
  </head>
  <body>
    <nav id="main-nav">
      <span class="main-nav__toggle">
        <a href="#" onclick="openSideMenu()">
          <svg width="30" height="30">
            <path d="M0,5 30,5" stroke="#fff" stroke-width="5" />
            <path d="M0,14 30,14" stroke="#fff" stroke-width="5" />
            <path d="M0,23 30,23" stroke="#fff" stroke-width="5" />
          </svg>
        </a>
      </span>
      <ul class="main-nav__links">
        <li><a href="#home">Home</a></li>
        <li><a href="#about">About</a></li>
        <li><a href="#blog">Blog</a></li>
        <li><a href="#contact">Contact</a></li>
      </ul>
    </nav>
    <main id="main">
      <div id="main__content">
        <h1>Responsive Side Nav</h1>
        <p>Reduce screen size to < 568px to see side nav toggle</p>
      </div>
      <div id="side-nav">
        <a href="#" class="btn-close" onclick="closeSideMenu()">×</a>
        <a href="#home">Home</a>
        <a href="#about">About</a>
        <a href="#blog">Blog</a>
        <a href="#contact">Contact</a>
      </div>
    </main>

    <script>
      function openSideMenu() {
        document.getElementById("side-nav").style.width = "250px"
        document.getElementById("main__content").style.marginLeft = "250px"
      }

      function closeSideMenu() {
        document.getElementById("side-nav").style.width = "0"
        document.getElementById("main__content").style.marginLeft = "0"
      }
    </script>
  </body>
</html>

Let’s style this thing up, shall we?

Styling the Sidebar Menu With CSS

First, I decided to reset all styles by adding the asterisks (*) to the top of my CSS file, giving the entire thing a margin and a padding of 0. The (*) selector basically selects all elements.

To make this thing look a little nicer, I’m also changing the font-family within the body to Open Sans, with Arial and sans-serif as a fallback.

This will look nicer than the standard font.

* {
  margin: 0;
  padding: 0;
}

body {
  font-family: "Open Sans", Arial, sans-serif;
}

Now, let’s focus on our #main-nav and #side-nav elements.

Styling The Horizontal Menu

First, we set the navigation menu height to 63px.

Why 63 and not 60?

Well, there is no reason, but it makes it easier to align the hamburger toggle vertically in the center.

For the ul tag, I’m removing the bullet points (Come on, who uses bullet points anyway?)

I also position it with position: absolute.

(Note: If you’re still confused about positioning in CSS and how it works, here’s how I learned it.)

Let’s also add a bit of margin to the top, bottom and left and we’re almost there. This is how your main nav styling should look like:

#main-nav {
  height: 63px;
  top: 0;
  background-color: #111;
}

#main-nav ul {
  position: absolute;
  top: 0;
  margin: 10px 0 10px 60px;
  list-style-type: none;
}

#main-nav ul li {
  display: inline-block;
  padding: 10px 10px;
}

#main-nav li a {
  display: block;
  float: left;
  text-align: center;
  font-size: 18px;
  text-decoration: none;
  color: #fff;
  padding: 5px;
}

#main-nav .main-nav__links a:hover {
  background-color: #ddd;
  color: #000;
}

For the list elements itself, we want those to be displayed as inline-block.

For the links (the a’s), those should float to the left and we might want to also increase the font-size to 18px. Let’s also add a tiny bit of padding to all sides.

Styling The Sidebar Menu

For the sidebar menu navigation, I set the width to 0px.

Remember, our Javascript will extend this to 250 when clicking on the hamburger toggle?

I’m also adding opacity to the background and a set the z-index to 1.

The z-index ensures that the sidebar menu will always overlap any other content. It basically prevents it from looking weird.

We’ll set the height to 100% to cover the entire screen, we set the position to fixed and make sure that we don’t see any ugly scrollbar. To do this, we simply add overflow-x: hidden

Let’s add some transitions as well. Adding this

transition: 0.3s;

to our CSS will ensure that the sidebar opens smoothly. We don’t want it to open abruptly, right?

One thing I haven’t mentioned are the media queries:

I decided to hide the Hamburger toggle for screen sizes wider than 568px and hide the navigation links for any screen smaller than that. To use media queries or not is entirely up to you, but I felt it looked nicer and made more sense.

Wrapping up, your final CSS file should look like this:

* {
  margin: 0;
  padding: 0;
}

body {
  font-family: "Open Sans", Arial, sans-serif;
}

#main-nav {
  height: 63px;
  top: 0;
  background-color: #111;
}

#main-nav ul {
  position: absolute;
  top: 0;
  margin: 10px 0 10px 60px;
  list-style-type: none;
}

#main-nav ul li {
  display: inline-block;
  padding: 10px 10px;
}

#main-nav li a {
  display: block;
  float: left;
  text-align: center;
  font-size: 18px;
  text-decoration: none;
  color: #fff;
  padding: 5px;
}

#main-nav .main-nav__links a:hover {
  background-color: #ddd;
  color: #000;
}

#side-nav {
  height: 100%;
  width: 0;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: #111;
  overflow-x: hidden;
  padding-top: 60px;
  opacity: 0.95;
  transition: 0.3s;
}

#side-nav a {
  padding: 10px 10px 10px 30px;
  text-decoration: none;
  font-size: 18px;
  color: #ccc;
  display: block;
}

#side-nav a:hover {
  color: #fff;
}

#side-nav .btn-close {
  position: absolute;
  top: 0;
  right: 22px;
  font-size: 36px;
}

.main-nav__toggle svg {
  margin-top: 18px;
  margin-left: 15px;
}

#main {
  transition: margin-left 0.3s;
  width: 100%;
  padding: 20px;
  margin-right: 20px;
}

@media screen and (max-width: 568px) {
  .main-nav__links {
    display: none;
  }
}

@media screen and (min-width: 568px) {
  .main-nav__toggle {
    display: none;
  }

  #main-nav .main-nav__links {
    margin-left: 10px;
  }
}

There you go, a simple responsive sidebar menu with minimal markup and only a few lines of CSS and JS.

Fancy the full code? You can find it on my GitHub profile. To watch the full video tutorial by Brad Traversy on Youtube, go here.

Conclusion

Hope you found this tutorial and the code examples helpful. If you have any questions, connect with me on Twitter on LinkedIn.

(Visited 49 times, 1 visits today)