Creating a Sidebar with HTML, CSS and JS
Tags: beginners, css, javascript, html
Published: 2020-01-27 00:56:01

---
title: Creating a Sidebar with HTML, CSS and JS
published: true
description: How to create a simple and useful sidebar using vanilla technologies
tags: #beginners #css #javascript #html
cover_image: https://images.unsplash.com/photo-1551672263-79036d524f6a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80
---

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.

```html
<div id="sidebar1" class="sidebar">
  <div class="sidebar__content">
    <span>whatever you want</span>
  </div>
</div>
```

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).

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

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:

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

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:

```css
/* 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);
}
```

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:

```js
// 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); 
     }
   });
});
```

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:

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

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:

{% codepen https://codepen.io/felipperegazio/pen/oNgVOyv %}

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.