NAVIGATION

Expandable Sidebar Navigation

A clean responsive sidebar navigation with smooth collapse and expand behavior, grouped menu sections, active states and notification badges.

HTML
<div class="cr-play-sidebar">

  <div class="cr-play-brand">

    <div class="cr-play-logo">N</div>

    <div class="cr-play-brand-text">
      <strong>CodeRipple</strong>
      <span>BUILD FASTER</span>
    </div>

    <button
      class="cr-play-collapse-btn"
      type="button"
      aria-label="Collapse sidebar">
      ‹
    </button>

  </div>


  <div class="cr-play-section">

    <div class="cr-play-section-title">Menu</div>

    <nav class="cr-play-nav">

      <a href="#" class="cr-play-item active">

        <span class="cr-play-icon">
          <svg viewBox="0 0 24 24">
            <path d="M3 11.5 12 4l9 7.5"></path>
            <path d="M5.5 10.5V20h13v-9.5"></path>
            <path d="M9.5 20v-6h5v6"></path>
          </svg>
        </span>

        <span class="cr-play-label">Home</span>

      </a>


      <a href="#" class="cr-play-item">

        <span class="cr-play-icon">
          <svg viewBox="0 0 24 24">
            <path d="m8 5 10 7-10 7Z"></path>
          </svg>
        </span>

        <span class="cr-play-label">
          Continue watching
        </span>

      </a>


      <a href="#" class="cr-play-item">

        <span class="cr-play-icon">
          <svg viewBox="0 0 24 24">
            <path d="M12 5v14"></path>
            <path d="M5 12h14"></path>
          </svg>
        </span>

        <span class="cr-play-label">My list</span>
        <span class="cr-play-badge">7</span>

      </a>


      <a href="#" class="cr-play-item">

        <span class="cr-play-icon">
          <svg viewBox="0 0 24 24">
            <rect x="4" y="7" width="16" height="12" rx="2"></rect>
            <path d="m8 4 2 3"></path>
            <path d="m16 4-2 3"></path>
          </svg>
        </span>

        <span class="cr-play-label">Series</span>

      </a>


      <a href="#" class="cr-play-item">

        <span class="cr-play-icon">
          <svg viewBox="0 0 24 24">
            <rect x="5" y="4" width="14" height="16" rx="2"></rect>
            <path d="M8 4v16"></path>
            <path d="M16 4v16"></path>
            <path d="M5 8h3"></path>
            <path d="M5 12h3"></path>
            <path d="M5 16h3"></path>
            <path d="M16 8h3"></path>
            <path d="M16 12h3"></path>
            <path d="M16 16h3"></path>
          </svg>
        </span>

        <span class="cr-play-label">Movies</span>

      </a>


      <a href="#" class="cr-play-item">

        <span class="cr-play-icon">
          <svg viewBox="0 0 24 24">
            <path d="M8 9h8a5 5 0 0 1 4.6 7l-1 2.2a2 2 0 0 1-3.4.5L14.8 17H9.2l-1.4 1.7a2 2 0 0 1-3.4-.5l-1-2.2A5 5 0 0 1 8 9Z"></path>
            <path d="M8 12v4"></path>
            <path d="M6 14h4"></path>
            <circle cx="16.5" cy="13" r=".7"></circle>
            <circle cx="18" cy="15" r=".7"></circle>
          </svg>
        </span>

        <span class="cr-play-label">Games</span>

      </a>

    </nav>

  </div>


  <div class="cr-play-divider"></div>


  <div class="cr-play-section">

    <div class="cr-play-section-title">Discovery</div>

    <nav class="cr-play-nav">

      <a href="#" class="cr-play-item">

        <span class="cr-play-icon">
          <svg viewBox="0 0 24 24">
            <rect x="4" y="4" width="6" height="6" rx="1"></rect>
            <rect x="14" y="4" width="6" height="6" rx="1"></rect>
            <rect x="4" y="14" width="6" height="6" rx="1"></rect>
            <rect x="14" y="14" width="6" height="6" rx="1"></rect>
          </svg>
        </span>

        <span class="cr-play-label">Releases</span>

      </a>


      <a href="#" class="cr-play-item">

        <span class="cr-play-icon">
          <svg viewBox="0 0 24 24">
            <path d="m12 3 2.6 5.3 5.9.9-4.3 4.2 1 5.9-5.2-2.8-5.2 2.8 1-5.9-4.3-4.2 5.9-.9Z"></path>
          </svg>
        </span>

        <span class="cr-play-label">Popular</span>

      </a>

    </nav>

  </div>


  <div class="cr-play-divider"></div>


  <nav class="cr-play-nav cr-play-bottom">

    <a href="#" class="cr-play-item">

      <span class="cr-play-icon">
        <svg viewBox="0 0 24 24">
          <circle cx="12" cy="12" r="3"></circle>
          <path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6V21h-4v-.1a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H3v-4h.1a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.3 7 7.1 4.2l.1.1a1.7 1.7 0 0 0 1.9.3A1.7 1.7 0 0 0 10 3h4a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9A1.7 1.7 0 0 0 21 10h.1v4H21a1.7 1.7 0 0 0-1.6 1Z"></path>
        </svg>
      </span>

      <span class="cr-play-label">Settings</span>

    </a>


    <a href="#" class="cr-play-item">

      <span class="cr-play-icon">
        <svg viewBox="0 0 24 24">
          <path d="M10 5H5v14h5"></path>
          <path d="M13 8l4 4-4 4"></path>
          <path d="M9 12h8"></path>
        </svg>
      </span>

      <span class="cr-play-label">Log out</span>

    </a>

  </nav>

</div>
CSS
*{
  box-sizing:border-box;
}

.cr-play-sidebar{
  width:280px;
  min-height:650px;
  padding:22px 18px 20px;
  background:#08111f;
  color:#94a3b8;
  border:1px solid rgba(34,211,238,.12);
  border-radius:26px;
  box-shadow:
    0 22px 55px rgba(0,0,0,.45),
    inset 0 1px 0 rgba(255,255,255,.025);
  transition:
    width .35s ease,
    padding .35s ease;
}

.cr-play-brand{
  position:relative;
  display:flex;
  align-items:center;
  min-height:52px;
  margin-bottom:24px;
}

.cr-play-logo{
  width:42px;
  height:42px;
  display:flex;
  align-items:center;
  justify-content:center;
  flex-shrink:0;
  border-radius:12px;
  background:#0d1828;
  border:1px solid rgba(34,211,238,.14);
  color:#22d3ee;
  font-size:17px;
  font-weight:900;
  cursor:pointer;
  box-shadow:
    0 6px 18px rgba(0,0,0,.24),
    inset 0 1px 0 rgba(255,255,255,.04);
}

.cr-play-brand-text{
  min-width:0;
  margin-left:12px;
  display:flex;
  flex-direction:column;
}

.cr-play-brand-text strong{
  color:#fff;
  font-size:16px;
  font-weight:800;
}

.cr-play-brand-text span{
  margin-top:3px;
  color:#64748b;
  font-size:9px;
  font-weight:700;
  letter-spacing:1.1px;
}

.cr-play-collapse-btn{
  width:32px;
  height:32px;
  margin-left:auto;
  padding:0;
  display:flex;
  align-items:center;
  justify-content:center;
  border:0;
  border-radius:9px;
  background:transparent;
  color:#64748b;
  font-size:25px;
  cursor:pointer;
}

.cr-play-collapse-btn:hover{
  background:#101a2b;
  color:#22d3ee;
}

.cr-play-section-title{
  margin:0 8px 10px;
  color:#516079;
  font-size:10px;
  font-weight:800;
  letter-spacing:2px;
  text-transform:uppercase;
}

.cr-play-nav{
  display:flex;
  flex-direction:column;
  gap:5px;
}

.cr-play-item{
  width:100%;
  min-height:42px;
  padding:0 13px;
  display:flex;
  align-items:center;
  border-radius:13px;
  color:#8f9caf;
  text-decoration:none;
  transition:
    background .2s ease,
    color .2s ease,
    box-shadow .2s ease;
}

.cr-play-item:hover{
  color:#e2e8f0;
  background:#0a1424;
  box-shadow:
    inset 3px 3px 7px rgba(0,0,0,.45),
    inset -2px -2px 5px rgba(255,255,255,.025);
}

.cr-play-item.active{
  color:#fff;
  background:
    linear-gradient(
      90deg,
      #0891b2 0%,
      #2563eb 48%,
      #7c3aed 100%
    );
}

.cr-play-icon{
  width:20px;
  height:20px;
  margin-right:12px;
  display:flex;
  align-items:center;
  justify-content:center;
  flex-shrink:0;
  color:#7f8ca2;
}

.cr-play-icon svg{
  width:17px;
  height:17px;
  fill:none;
  stroke:currentColor;
  stroke-width:1.8;
  stroke-linecap:round;
  stroke-linejoin:round;
}

.cr-play-item:hover .cr-play-icon{
  color:#22d3ee;
}

.cr-play-item.active .cr-play-icon{
  color:#fff;
}

.cr-play-label{
  font-size:13px;
  font-weight:500;
  white-space:nowrap;
}

.cr-play-badge{
  min-width:21px;
  height:21px;
  margin-left:auto;
  padding:0 6px;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius:999px;
  background:#7c3aed;
  color:#fff;
  font-size:10px;
  font-weight:800;
}

.cr-play-divider{
  height:1px;
  margin:19px 5px;
  background:rgba(148,163,184,.15);
}

.cr-play-sidebar.is-collapsed{
  width:82px;
  padding-left:14px;
  padding-right:14px;
}

.cr-play-sidebar.is-collapsed .cr-play-brand{
  justify-content:center;
}

.cr-play-sidebar.is-collapsed .cr-play-brand-text,
.cr-play-sidebar.is-collapsed .cr-play-collapse-btn,
.cr-play-sidebar.is-collapsed .cr-play-label,
.cr-play-sidebar.is-collapsed .cr-play-badge{
  display:none;
}

.cr-play-sidebar.is-collapsed .cr-play-section-title{
  visibility:hidden;
  height:10px;
  margin-bottom:6px;
}

.cr-play-sidebar.is-collapsed .cr-play-item{
  width:48px;
  margin:0 auto;
  padding:0;
  justify-content:center;
}

.cr-play-sidebar.is-collapsed .cr-play-icon{
  margin-right:0;
}

.cr-play-sidebar.is-collapsed .cr-play-item:hover{
  background:#0a1424;
  box-shadow:
    inset 3px 3px 7px rgba(0,0,0,.50),
    inset -2px -2px 5px rgba(255,255,255,.03);
}
JavaScript
const sidebar = document.querySelector('.cr-play-sidebar');
const toggle = document.querySelector('.cr-play-collapse-btn');
const logo = document.querySelector('.cr-play-logo');

if (sidebar && toggle && logo) {

  toggle.addEventListener('click', function () {
    sidebar.classList.add('is-collapsed');
  });

  logo.addEventListener('click', function () {

    if (
      sidebar.classList.contains('is-collapsed')
    ) {
      sidebar.classList.remove('is-collapsed');
    }

  });

}

How This Expandable Sidebar Navigation Works

The Expandable Sidebar Navigation is a vertical menu that switches between a full 280px sidebar and a compact 82px icon-only state. Its HTML is divided into a brand area, Menu and Discovery sections, separators, and a bottom navigation group containing Settings and Log out.

The brand area contains a square CodeRipple logo marked with “N”, brand text, and a collapse button. Below it, the main navigation includes Home, Continue watching, My list, Series, Movies, and Games. A second section adds Releases and Popular, while the final group contains Settings and Log out. Each item uses an inline SVG icon and text label, and My list also includes a badge displaying 7.

The main .cr-play-sidebar starts at 280px wide with a minimum height of 650px. Its dark #08111f background is paired with a subtle cyan border, 26px rounded corners, an external shadow, and a small inset highlight. The width and horizontal padding use .35s transitions, which allows the entire sidebar to resize smoothly when its state changes.

Navigation items are arranged vertically with Flexbox. Each .cr-play-item has a minimum height of 42px and a 13px border radius. Inactive items use muted text and icon colors. Hovering changes the background to #0a1424, lightens the text, turns the icon cyan, and applies two inset shadows to create a slightly recessed appearance.

Home is marked with the active class in the supplied HTML. The active item uses a horizontal gradient from #0891b2 through #2563eb to #7c3aed. Its label and SVG icon are both white, clearly separating the selected option from the other navigation entries.

The collapsed layout is controlled by the .is-collapsed class. When this class is applied, the sidebar width changes from 280px to 82px and its left and right padding become 14px. Brand text, the collapse button, navigation labels, and the numeric badge are hidden with display: none.

Section titles are handled slightly differently. Instead of being removed completely, they use visibility: hidden, retain a 10px height, and receive a smaller bottom margin. This preserves some of the original vertical spacing while removing the visible “Menu” and “Discovery” text.

Navigation items also adapt to the compact layout. Each one becomes 48px wide, is centered with automatic horizontal margins, and loses its normal horizontal padding. The icon’s right margin changes from 12px to zero, leaving the SVG centered inside the compact button. For more detail about these state-dependent selectors, see the MDN CSS class selectors documentation.

JavaScript keeps the expand and collapse behavior simple. It selects the sidebar, collapse button, and logo. Clicking the collapse button adds is-collapsed to the sidebar. Once collapsed, the collapse button itself is hidden, so the logo becomes the way to restore the full layout. Clicking the logo checks whether is-collapsed is present and removes it when necessary.

Unlike some navigation components, this script does not change the active navigation item when links are clicked. Its JavaScript is specifically responsible for the sidebar’s collapsed and expanded states.

Customizing the Expandable Sidebar Navigation

The existing structure provides several useful values that can be adjusted to fit a dashboard, media interface, or application layout.

  • Change the expanded 280px and collapsed 82px widths to control how much horizontal space each state occupies.
  • Adjust the .35s width and padding transitions to change the collapse animation speed.
  • Replace the brand name, “BUILD FASTER” subtitle, and “N” logo character with your own identity.
  • Edit the navigation labels and inline SVG paths to represent different sections.
  • Change the active gradient colors #0891b2, #2563eb, and #7c3aed to match another interface palette.
  • Modify the 42px regular item height or 48px collapsed item width to change navigation sizing.
  • Change the 7 inside .cr-play-badge to display a different count.
  • Adjust the dark backgrounds, cyan hover color #22d3ee, borders, and inset shadows to alter the visual style.

Where to Use This Expandable Sidebar Navigation

This component is suited to interfaces that need several navigation destinations but also benefit from reclaiming horizontal screen space.

  • Streaming and media dashboards
  • Admin panels and management tools
  • SaaS application interfaces
  • Developer dashboards
  • Content libraries with grouped navigation
  • Desktop-style web applications

The separate Menu, Discovery, and bottom navigation areas make it practical for interfaces with multiple types of destinations. For a more compact navigation control with fewer options, the Neumorphic Pill Navigation provides a horizontal four-button layout instead.

Frequently Asked Questions

How does the Expandable Sidebar Navigation collapse?

Clicking .cr-play-collapse-btn makes JavaScript add the is-collapsed class. CSS then reduces the sidebar from 280px to 82px and hides its text-based elements.

How do you expand the sidebar again?

After the sidebar is collapsed, clicking .cr-play-logo checks for the is-collapsed class and removes it. The sidebar then returns to its full-width state.

What happens to navigation labels when the sidebar is collapsed?

The brand text, navigation labels, badge, and collapse button are hidden with display: none. Navigation items become 48px-wide centered controls containing only their SVG icons.

Does clicking a navigation item change the active state?

No. The supplied JavaScript only handles collapsing and expanding the sidebar. Home has the active class in the HTML, but there is no JavaScript listener that moves this class when another navigation link is clicked.

The Expandable Sidebar Navigation uses CSS state selectors and a small JavaScript class toggle system to switch between a detailed navigation panel and a space-saving icon-only layout.

Scroll to Top