Creating a Sidebar with HTML, CSS and JS

Felippe Regazio - Jan 27 '20 - - Dev Community

No bla bla bla. Lets do the job: To create a simple sidebar, you'll need to solve 3 main tasks:

  1. Create a proper structure (HTML)
  2. Add style and position (CSS)
  3. Add open/close behavior (JS)

[Codepen link at the end of the post]

So lets start by the HTML. We will create a div that is fixed on the right side of the screen. I'd like to add a comment about a rule i created for myself when writing medium to large HTML: Never add or organize the content directly on the "grand parent" element, this will keep you away from trouble.

<div id="sidebar1" class="sidebar">
  <div class="sidebar__content">
    <span>whatever you want</span>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

As we are writing a sidebar, we could do it with only one div, but this is not good for scalability, as i said. So, we will use the .sidebar div as the holder and .sidebar__content for content - duhhh :P

If you're thinking about accessibility (and you should), you'll maybe need the nav or the aside tag, depending on the way - and where - you're implementing your sidebar. This also would change the element role. As we are having a very basic conversation about it, i suggest you to (if you dont know about this things yet) ask google about HTML semantics and accessibility to complement this tutorial.

We will use aria attributes to manage the sidebar states, if you dont know about aria, you can start by this link: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA.

Lets suppose im adding a main sidebar on my page. So, we will use the aria-label to name the main sidebar, and the aria-hidden to manage its state (visible or not).

<div id="sidebar1" class="sidebar" aria-label="Main sidebar containing navigation links and some information" aria-hidden="true">
  <div class="sidebar__content">
    <span>whatever you want</span>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Now we already have our structure. Lets add the style. We will use the "aria-hidden" attribute on the CSS to determine when the sidebar is visible or not. But first, lets care about the position:

body {
  min-height: 100vh;
}
/* SIDEBAR POSITION */
.sidebar {
  background-color: #f1f1f1;
  height: 100vh;
  position: fixed;
  top: 0;
  right: 0;
  min-width: 300px;
}
.sidebar__content {
  padding: 8px;
  overflow-y: scroll;
  overflow-x: hidden;
}
Enter fullscreen mode Exit fullscreen mode

At the "sidebar position" part of the css, we are telling the sidebar to be fixed on the right side of the screen, and also keep the screen height as its own height, acting like a fixed holder.

Then we determine that the content will have some padding and will be vertically scrollable when needed.

Now lets show/hide our sidebar. To do that we will translate (move) our sidebar out of the viewport. As our sidebar is on the right side, we need to move our sidebar to the right. The minimum and necessary distance that the sidebar needs to be translated is its own width, or 100% of itself.

As i said, we will use the aria-hidden as our state manager, so our rule is simple: when the sidebar has the aria-hidden true, we will move it out of the view port by translating it 100% (its whole size) to the right. When the sidebar hasn't aria-hidden or has aria-hidden false, we will remove the translate putting the sidebar back on its original position:

/* SIDEBAR HIDDEN STATE */
.sidebar[aria-hidden="true"] {
  transition: 200ms;
  transform: translateX(100%);
}
/* SIDEBAR VISIBLE STATE */
.sidebar:not([aria-hidden]),
.sidebar[aria-hidden="false"] {
  transition: 200ms;
  transform: translateX(0);
}
Enter fullscreen mode Exit fullscreen mode

Note the .sidebar:not([aria-hidden]) rule. That means that not only the aria-hidden false but also the absence of the aria-hidden attribute will show the sidebar. So you can use the JS to set true/false or add/remove on the attribute. Anyway we will avoid to remove the aria attribute, so we will manage the sidebar visibility by setting true/false on the aria-hidden attribute from a JS script.

With JS we will create a data attribute that holds a sidebar id. We will call it data-toggle-sidebar. The element with this attribute will query the document by the passed sidebar id, and - guess what - WILL TOGGLE IT by alternating the aria-hidden value u.u

Here is the code:

// Catch all the `[data-toggle-sidebar]` elements on the document.
document.querySelectorAll('[data-toggle-sidebar]').forEach(toggle => {
   // Add an event listener on those elements "click" event
   toggle.addEventListener('click', e => {
     // get the sidebar ID from the current element data attribute
     const sidebarID = toggle.dataset.toggleSidebar;
     // check if there is an element on the doc with the id
     const sidebarElement = sidebarID ? document.getElementById(sidebarID) : undefined;
     // if there is a sidebar with the passed id (data-toggle-sidebar)
     if (sidebarElement) {
        // toggle the aria-hidden state of the given sidebar
        let sidebarState = sidebarElement.getAttribute('aria-hidden');
        sidebarElement.setAttribute('aria-hidden', sidebarState == 'true' ? false : true); 
     }
   });
});
Enter fullscreen mode Exit fullscreen mode

By the commented code above you can easily know what the JS code does. In a few words: when a data-toggle-sidebar element is clicked, we will use its value as ID to search for a sidebar on the document. If the element (sidebar) exists, it will invert its aria-hidden value, toggling the sidebar visibility :)

Lets come back to our HTML and add a button to test our toggle function.
You must add the button as the example below:

<div id="sidebar1" class="sidebar" aria-label="Main sidebar containing navigation links and some information" aria-hidden="true">
  <div class="sidebar__content">
    <span>whatever you want</span>
  </div>
</div>

<button data-toggle-sidebar="sidebar1" aria-label="Toggle the document main sidebar visibility">Toggle Sidebar</button>
Enter fullscreen mode Exit fullscreen mode

Now you can add as many sidebars as you want (with different id's of course), and use the attribute data-toggle-sidebar to toggle them by passing the sidebar id as the attribute value. The sidebar will be toggled on the click event of the data-toggle-sidebar element.

At the end, you must have this result:

By here, you can improve your sidebar, adding a better support to the accessibility question, adding new features as close when clicked out of the sidebar, care about what happens when i open a new sidebar with another one already opened, a full responsive approach on the CSS, etc... This can be a cool trigger for new studies.

Cover image by Henry & Co. on Unsplash

Thats all folks.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player