DEV Community

Cover image for Creating a material design sidenav using pure JavaScript
manu
manu

Posted on • Edited on

3 1

Creating a material design sidenav using pure JavaScript

The sidenav components are designed to add side content to a fullscreen app. The drawer component is designed to add side content to a small section of your app.

Here's how to achieve this using pure JS!

Codepen: https://codepen.io/ManuTheCoder/pen/YzZVyjo

Step 1 - Creating the HTML

We're going to use the Material Icons webfont for the icons

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
Enter fullscreen mode Exit fullscreen mode

Here's the code for the sidenav:

<a href="#" onclick="sidenav.open('demo_sidenav')">Open Sidenav</a>
<div id="demo_sidenav" class="sidenav">
  <ul>
    <li><a href="#" class="active_link"><i class="material-icons">home</i> Home</a></li>
    <li><a href="#"><i class="material-icons">book</i> News</a></li>
    <li><a href="#"><i class="material-icons">forum</i> Forum</a></li>
    <li><a href="#"><i class="material-icons">help</i> Help</a></li>
    <li><a href="#"><i class="material-icons">settings</i> Settings</a></li>
  </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

If you noticed one link has a class containing active_link. This highlights the a link to make it look active. This is optional, though

Step 2 - Creating the CSS

So, we're going to create a overlay for the sidenav. Notice that it isn't in the HTML section. This is because we are going to create an element using javascript's createElement feature.

.sidenav-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index:99;
    background: #212121;
    transition: all .2s;
    background: rgba(0,0,0,0.3)
  }
Enter fullscreen mode Exit fullscreen mode

Then some basic styles for the sidenav links

.sidenav ul {
    list-style-type: none;
    padding:0;
  }
  .sidenav ul li a {
    line-height: 45px;
    text-decoration: none;
    color: #6e6e6e;
    padding: 0 10px;
    display: block;
    margin: 5px;
    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
    border-radius: 5px;
  }
Enter fullscreen mode Exit fullscreen mode

Let's define a class for an active link

.active_link {
    background: rgba(10, 113, 209, .1);
    color: #0a71d1 !important;
    pointer-events: none
  }
Enter fullscreen mode Exit fullscreen mode

Sidenav main code

  .sidenav {
    overflow-y:scroll;
    width: 300px;
    height: 100vh;
    display: block;
    position:fixed;
    top:0;
    left: -300px;
    z-index: 9999999999999999;
    transition: left .2s;
    z-index:999;
    background: white;
  }
Enter fullscreen mode Exit fullscreen mode

And, let's adjust the icons a bit

  .sidenav ul li a i {
    font-size: 24px;
    position: relative;
    bottom: -7px;
    margin-right: 10px
  }
Enter fullscreen mode Exit fullscreen mode

The fun part - JavaScript!

Let's create a sidenav overlay using the createElement feature in JavaScript

  var sidenav_overlay = document.createElement('div');
  sidenav_overlay.className = "sidenav-overlay";
  sidenav_overlay.id = "sidenav-overlay";
  document.body.appendChild(sidenav_overlay);
Enter fullscreen mode Exit fullscreen mode

And, the sidenav code

So, we're going to create an object sidenav. This will be used to open and close the sidenav

  const sidenav = {
    open: function(selector) {
      document.getElementById(selector).style.left = "0";
      var x = document.getElementById('sidenav-overlay');
      x.style.display = "block";
      x.style.opacity = 0;
      setTimeout(function() {x.style.opacity = 1;}, 10)
      x.onclick = function() {sidenav.close(selector)};
    }
  }
Enter fullscreen mode Exit fullscreen mode

... and to close the sidenav...

const sidenav = {
   // ...
close: function(selector) {
      document.getElementById(selector).style.left = '-300px';
      var x = document.getElementById('sidenav-overlay');
      x.style.opacity = 0;
      setTimeout(function() {x.style.display = "none";}, 200);
    },
}
Enter fullscreen mode Exit fullscreen mode

Final code:

<!DOCTYPE html>
<html>
  <head>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <style>
      .sidenav-overlay {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index:99;
        background: #212121;
        transition: all .2s;
        background: rgba(0,0,0,0.3)
      }
      .sidenav ul {
        list-style-type: none;
        padding:0;
      }
      .sidenav ul li a {
        line-height: 45px;
        text-decoration: none;
        color: #6e6e6e;
        padding: 0 10px;
        display: block;
        margin: 5px;
        font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
        border-radius: 5px;
      }
      .active_link {
        background: rgba(10, 113, 209, .1);
        color: #0a71d1 !important;
        pointer-events: none
      }
      .sidenav {
        overflow-y:scroll;
        width: 300px;
        height: 100vh;
        display: block;
        position:fixed;
        top:0;
        left: -300px;
        z-index: 9999999999999999;
        transition: left .2s;
        z-index:999;
        background: white;
      }
      .sidenav ul li a i {
        font-size: 24px;
        position: relative;
        bottom: -7px;
        margin-right: 10px
      }
    </style>
  </head>
  <body>
    <a href="#" onclick="sidenav.open('demo_sidenav')">Open Sidenav</a>
    <div id="demo_sidenav" class="sidenav">
      <ul>
        <li><a href="#" class="active_link"><i class="material-icons">home</i> Home</a></li>
        <li><a href="#"><i class="material-icons">book</i> News</a></li>
        <li><a href="#"><i class="material-icons">forum</i> Forum</a></li>
        <li><a href="#"><i class="material-icons">help</i> Help</a></li>
        <li><a href="#"><i class="material-icons">settings</i> Settings</a></li>
      </ul>
    </div>
    <script>
      const sidenav = {
        open: function(selector) {
          document.getElementById(selector).style.left = "0";
          var x = document.getElementById('sidenav-overlay');
          x.style.display = "block";
          x.style.opacity = 0;
          setTimeout(function() {x.style.opacity = 1;}, 10)
          x.onclick = function() {sidenav.close(selector)};
        },
        close: function(selector) {
          document.getElementById(selector).style.left = '-300px';
          var x = document.getElementById('sidenav-overlay');
          x.style.opacity = 0;
          setTimeout(function() {x.style.display = "none";}, 200);
        },
      }
      var sidenav_overlay = document.createElement('div');
      sidenav_overlay.className = "sidenav-overlay";
      sidenav_overlay.id = "sidenav-overlay";
      document.body.appendChild(sidenav_overlay);
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more