A Collapsible Sidebar

how to make a collapsible sidebar menu

    A collapsible sidebar is helpful for smaller screen sizes and dashboards when needed for space. It can be made in many ways, one of which is using HTML, CSS and Javascript. You can follow step by step below or go to JSFiddle working demo. In this case, the idea is to change the width of the sidebar and left margin of the main content. And transition the changes smoothly.


<!DOCTYPE html>
<html lang="en">
  <meta charset="UTF-8">
  <div class="sidebar">
    <span class="close">&times;</span>
    <a href="#">About</a>
    <a href="#">Services</a>
    <a href="#">Clients</a>
    <a href="#">Contact</a>
  <div class="main">
    <div class="main-header">
      <span class="hamburger">&#9776;</span>
    <div class="main-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure, eos. Numquam eveniet nulla voluptates, unde sed odio minus placeat! Molestias deleniti vero soluta, illum quod asperiores excepturi ut quibusdam dolorum magnam inventore at ipsam beatae qui tenetur, accusantium, consequuntur. Libero architecto officiis, amet, labore quibusdam vel modi totam, repellat quam magnam necessitatibus sit cumque asperiores laboriosam. Odit quas quaerat, quibusdam eius non, recusandae deleniti tempora veritatis illo ipsa alias hic saepe officiis ipsam nobis. Architecto consequatur atque harum neque omnis voluptas non repudiandae quibusdam rem eius possimus, velit est! Aperiam distinctio atque, eligendi consequatur optio nostrum error dolore velit accusantium.</div>


    Two div elements side by side: sidebar and main. Sidebar consists of a closing span (X) and links.


body {
  margin: 0;
  padding: 0;
  height: 100vh;
  font-family: "Lato", sans-serif;


    Resetting the page margin and padding and giving it full height.


.sidebar {
  height: 100%;
  width: 0;
  background-color: black;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1;
  overflow-x: hidden;
  padding-top: 4rem;
  transition: 0.5s;


    The initial height is the full height of the body and the width is set to zero. It is not required, depending on the use case it could be set to anything you need. The position is fixed to prevent flow with a document. The z-index set to 1 means it is the top layer. Overflow hidden prevents links to be seen when the width is 0. The padding-top gives room for the closing span and transition is used to sidebar smoothly appear and disappear.


.sidebar a {
  padding: 0.5rem 0.5rem 0.5rem 2rem;
  text-decoration: none;
  font-size: 1.5rem;
  color: #818181;
  display: block;
  transition: 0.3s;

.sidebar a:hover {
  color: #f2f2f2;


    Styling links for a nice visual appearance. The default style is outdated and somehow ugly.


.sidebar .close {
  position: absolute;
  top: 0;
  right: 1.5rem;
  font-size: 2.5rem;
  margin-left: 60px;
  cursor: pointer;

.sidebar .close:hover {
  color: #f2f2f2;


    Positioning the closing span at the top right corner of the sidebar and styling it accordingly.


.main {
  background-color: #f4f4f4;
  height: 100%;
  transition: margin-left .5s;

.main-header {
  background-color: white;
  padding: 0.3rem 1rem;
  box-shadow: 0px 0px 18px 0px rgba(0,0,0,0.2);

.main-body {
  padding: 1rem;

.hamburger {
  font-size: 2rem;
  cursor: pointer;


    Styling and transitioning the main div's margin-left.


const sidebar = document.querySelector('.sidebar')
const main = document.querySelector('.main')
const hamburger = document.querySelector('.hamburger')
const close = document.querySelector('.close')

hamburger.addEventListener('click', () => {
  main.style.marginLeft = '15rem'
  sidebar.style.width = '15rem'

close.addEventListener('click', () => {
  main.style.marginLeft = '0'
  sidebar.style.width = '0'


    The Javascript part is also simple, as it should be. First, we are getting all elements we need for interaction. Lastly, clickable elements get event listeners to click. On opening, the sidebar gets the width and the main gets the left margin. On closing vice versa. This is just one of many ways to accomplish sidebar visibility.