30 CSS Sidebar Layouts
06 / 30

All 30 in 30 CSS Sidebar Layouts

  1. 01Modern SaaS Dashboard Sidebar Menu with Native Dark Mode Switch
  2. 02Accessible Admin Panel Sidebar with CSS Tooltips and Icon Collapse
  3. 03Developer Documentation Sidebar with Scroll-Synced Nesting
  4. 04Mobile-First Responsive Sidebar to Bottom Navigation Switch Layout
  5. 05Data Analytics Sidebar Layout with CSS Subgrid Alignment
  6. 06Smooth Animated Collapsible Sidebar Menu with Icon-Only Mode
  7. 07CSS Position Sticky Sidebar Layout for E-Commerce and Blogs
  8. 08Pure CSS Collapsible Sidebar Drawer Menu without JavaScript
  9. 09CSS Fixed Sidebar Layout with Independent Scrollable Main Content
  10. 10Off-Canvas Navigation Drawer for Mobile & Desktop Web Apps
  11. 11Right-Aligned CSS Sidebar Layout for Secondary Tool Panels
  12. 12Two-Pane Webmail UI Layout with CSS Flexbox & Grid
  13. 13Dual Sidebar App Shell Layout with Left Nav and Right Context Panel
  14. 14Compact Mini Icon Rail Sidebar Navigation for SaaS Web Apps
  15. 15Responsive E-Commerce Product Filter Sidebar with Native Accordion Menu
  16. 16Modern Floating Glassmorphism Sidebar UI Component
  17. 17CSS Sidebar Menu with Sticky User Profile Footer
  18. 18Push Content Sidebar Navigation Layout with Smooth CSS Transitions
  19. 19Off-Canvas Sidebar Overlay Layout with Blur Backdrop
  20. 20Persistent Collapsible State Sidebar with CSS Variables
  21. 21App Sidebar Navigation with Integrated Sticky Search Bar
  22. 22Section-Grouped Sidebar Navigation Menu with Header Labels
  23. 23CSS Target Active Indicator Sidebar Menu without JavaScript
  24. 24Multi-Level Nested Tree Sidebar Navigation Layout
  25. 25Multi-Tab Sidebar UI Component with Dynamic Panel Switching
  26. 26Onboarding Wizard Sidebar Layout with Step Progress Tracking
  27. 27Pure CSS Resizable Sidebar Layout Using Resize Property
  28. 28Three-Pane Productivity Workspace Shell Layout
  29. 29Next-Gen Adaptive Sidebar Layout Using CSS Container Queries
  30. 30Frosted Glass Floating Sidebar Layout with Backdrop Blur
Pure CSSMIT licensed

Smooth Animated Collapsible Sidebar Menu with Icon-Only Mode

The polished shrink-to-rail collapse: 248px of labeled navigation eases down to a 68px icon rail in one motion — the grid track, the fading labels, and a rotating fold chevron all sharing a single 300ms curve. Labels fade BEFORE the track finishes (staggered transitions), which is the micro-detail that makes it feel engineered instead of animated.

Live Demo
Plain CSSTailwind v4
Try it

Mosaic by Cruip: a complete Tailwind admin dashboard template in HTML, React, Next.js and Vue · $69

Cruip · Mosaic by Cruip · Affiliate link

View Mosaic dashboard

The code

<section class="sbl-09">
  <input type="checkbox" id="sbl09-c" class="sbl-09__state">
  <aside class="sbl-09__rail">
    <div class="sbl-09__brand"><span class="sbl-09__mark" aria-hidden="true"></span><span class="sbl-09__word">Northwind</span></div>
    <nav class="sbl-09__nav" aria-label="Main">
      <a href="#" aria-current="page"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7.5" height="7.5" rx="1.5"/><rect x="13.5" y="3" width="7.5" height="7.5" rx="1.5"/><rect x="3" y="13.5" width="7.5" height="7.5" rx="1.5"/><rect x="13.5" y="13.5" width="7.5" height="7.5" rx="1.5"/></svg><span class="sbl-09__txt">Dashboard</span></a>
      <a href="#"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9"/><path d="M12 3a9 9 0 0 1 9 9h-9z"/></svg><span class="sbl-09__txt">Insights</span></a>
      <a href="#"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 7 12 3 4 7m16 0v10l-8 4-8-4V7m16 0-8 4M4 7l8 4m0 0v10"/></svg><span class="sbl-09__txt">Inventory</span></a>
      <a href="#"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="9" cy="8" r="3.5"/><path d="M3 20c0-3.3 2.7-5.5 6-5.5s6 2.2 6 5.5m1-13.5a3.5 3.5 0 0 1 0 7"/></svg><span class="sbl-09__txt">Team</span></a>
      <a href="#"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M12 2v3m0 14v3M2 12h3m14 0h3M4.9 4.9l2.1 2.1m10 10 2.1 2.1m0-14.2-2.1 2.1m-10 10-2.1 2.1"/></svg><span class="sbl-09__txt">Settings</span></a>
    </nav>
    <label for="sbl09-c" class="sbl-09__fold"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m14 6-6 6 6 6"/></svg><span class="sbl-09__txt">Collapse</span></label>
  </aside>
  <main class="sbl-09__main"><h1>Dashboard</h1><p>Watch the choreography: on collapse the labels fade first, then the rail narrows. On expand, the reverse.</p></main>
</section>
.sbl-09,
.sbl-09 *,
.sbl-09 *::before,
.sbl-09 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.sbl-09 {
  --panel: oklch(0.965 0.006 250);
  --ink: oklch(0.25 0.02 250);
  --mut: oklch(0.5 0.015 250);
  --line: oklch(0.89 0.008 250);
  --accent: oklch(0.52 0.16 250);
  display: grid;
  grid-template-columns: 248px 1fr;
  height: 100vh;
  height: 100dvh;
  font-family: system-ui,'Segoe UI',sans-serif;
  background: oklch(0.99 0.002 250);
  color: var(--ink);
  transition: grid-template-columns .3s cubic-bezier(.4,0,.2,1);
}

.sbl-09:has(#sbl09-c:checked) {
  grid-template-columns: 68px 1fr;
}

.sbl-09__state {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.sbl-09__rail {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  padding: 16px 10px;
  overflow: hidden;
}

.sbl-09__brand {
  display: grid;
  grid-template-columns: 28px 1fr;
  align-items: center;
  gap: 10px;
  padding: 4px 10px 18px;
  white-space: nowrap;
}

.sbl-09__mark {
  width: 28px;
  height: 28px;
  border-radius: 9px;
  background: conic-gradient(from 120deg,var(--accent),oklch(0.65 0.14 300));
}

.sbl-09__word {
  font: 700 15px/1 system-ui,sans-serif;
}

.sbl-09__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sbl-09__nav a,
.sbl-09__fold {
  display: grid;
  grid-template-columns: 20px 1fr;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 10px;
  font: 500 14px/1 system-ui,sans-serif;
  color: var(--mut);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .2s ease,color .2s ease;
}

.sbl-09__nav svg,
.sbl-09__fold svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sbl-09__fold svg {
  transition: rotate .3s cubic-bezier(.4,0,.2,1);
}

.sbl-09__txt,
.sbl-09__word {
  opacity: 1;
  transition: opacity .18s ease .12s;
}

.sbl-09:has(#sbl09-c:checked) .sbl-09__txt,
.sbl-09:has(#sbl09-c:checked) .sbl-09__word {
  opacity: 0;
  transition: opacity .18s ease;
}

.sbl-09:has(#sbl09-c:checked) .sbl-09__fold svg {
  rotate: 180deg;
}

.sbl-09__nav a:hover,
.sbl-09__fold:hover {
  color: var(--ink);
  background: color-mix(in oklab,var(--ink) 6%,transparent);
}

.sbl-09__nav a[aria-current="page"] {
  color: var(--accent);
  background: color-mix(in oklab,var(--accent) 12%,transparent);
}

.sbl-09__nav a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sbl-09:has(#sbl09-c:focus-visible) .sbl-09__fold {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sbl-09__fold {
  margin-top: auto;
}

.sbl-09__main {
  padding: 32px;
  overflow-y: auto;
}

.sbl-09__main h1 {
  font: 600 22px/1.2 system-ui,sans-serif;
  margin-bottom: 10px;
}

.sbl-09__main p {
  color: var(--mut);
  font-size: 14px;
  line-height: 1.6;
  max-width: 46ch;
  text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
  .sbl-09,
    .sbl-09 .sbl-09__txt,
    .sbl-09 .sbl-09__word,
    .sbl-09 .sbl-09__fold svg {
    transition: none;
  }
}
/* No JavaScript — the grid track animates 248px→68px; labels fade on a faster, asymmetrically-delayed transition for native-feeling choreography. */
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Sidebar Layout from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Smooth Animated Collapsible Sidebar Menu with Icon-Only Mode
Source: https://codefronts.com/layouts/css-sidebar-layouts/smooth-animated-collapsible-sidebar-menu-with-icon-only-mode/

The polished shrink-to-rail collapse: 248px of labeled navigation eases down to a 68px icon rail in one motion — the grid track, the fading labels, and a rotating fold chevron all sharing a single 300ms curve. Labels fade BEFORE the track finishes (staggered transitions), which is the micro-detail that makes it feel engineered instead of animated.
## HTML
```html
<section class="sbl-09">
  <input type="checkbox" id="sbl09-c" class="sbl-09__state">
  <aside class="sbl-09__rail">
    <div class="sbl-09__brand"><span class="sbl-09__mark" aria-hidden="true"></span><span class="sbl-09__word">Northwind</span></div>
    <nav class="sbl-09__nav" aria-label="Main">
      <a href="#" aria-current="page"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7.5" height="7.5" rx="1.5"/><rect x="13.5" y="3" width="7.5" height="7.5" rx="1.5"/><rect x="3" y="13.5" width="7.5" height="7.5" rx="1.5"/><rect x="13.5" y="13.5" width="7.5" height="7.5" rx="1.5"/></svg><span class="sbl-09__txt">Dashboard</span></a>
      <a href="#"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9"/><path d="M12 3a9 9 0 0 1 9 9h-9z"/></svg><span class="sbl-09__txt">Insights</span></a>
      <a href="#"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 7 12 3 4 7m16 0v10l-8 4-8-4V7m16 0-8 4M4 7l8 4m0 0v10"/></svg><span class="sbl-09__txt">Inventory</span></a>
      <a href="#"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="9" cy="8" r="3.5"/><path d="M3 20c0-3.3 2.7-5.5 6-5.5s6 2.2 6 5.5m1-13.5a3.5 3.5 0 0 1 0 7"/></svg><span class="sbl-09__txt">Team</span></a>
      <a href="#"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M12 2v3m0 14v3M2 12h3m14 0h3M4.9 4.9l2.1 2.1m10 10 2.1 2.1m0-14.2-2.1 2.1m-10 10-2.1 2.1"/></svg><span class="sbl-09__txt">Settings</span></a>
    </nav>
    <label for="sbl09-c" class="sbl-09__fold"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m14 6-6 6 6 6"/></svg><span class="sbl-09__txt">Collapse</span></label>
  </aside>
  <main class="sbl-09__main"><h1>Dashboard</h1><p>Watch the choreography: on collapse the labels fade first, then the rail narrows. On expand, the reverse.</p></main>
</section>
```
## CSS
```css
.sbl-09,
.sbl-09 *,
.sbl-09 *::before,
.sbl-09 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.sbl-09 {
  --panel: oklch(0.965 0.006 250);
  --ink: oklch(0.25 0.02 250);
  --mut: oklch(0.5 0.015 250);
  --line: oklch(0.89 0.008 250);
  --accent: oklch(0.52 0.16 250);
  display: grid;
  grid-template-columns: 248px 1fr;
  height: 100vh;
  height: 100dvh;
  font-family: system-ui,'Segoe UI',sans-serif;
  background: oklch(0.99 0.002 250);
  color: var(--ink);
  transition: grid-template-columns .3s cubic-bezier(.4,0,.2,1);
}

.sbl-09:has(#sbl09-c:checked) {
  grid-template-columns: 68px 1fr;
}

.sbl-09__state {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.sbl-09__rail {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  padding: 16px 10px;
  overflow: hidden;
}

.sbl-09__brand {
  display: grid;
  grid-template-columns: 28px 1fr;
  align-items: center;
  gap: 10px;
  padding: 4px 10px 18px;
  white-space: nowrap;
}

.sbl-09__mark {
  width: 28px;
  height: 28px;
  border-radius: 9px;
  background: conic-gradient(from 120deg,var(--accent),oklch(0.65 0.14 300));
}

.sbl-09__word {
  font: 700 15px/1 system-ui,sans-serif;
}

.sbl-09__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sbl-09__nav a,
.sbl-09__fold {
  display: grid;
  grid-template-columns: 20px 1fr;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 10px;
  font: 500 14px/1 system-ui,sans-serif;
  color: var(--mut);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .2s ease,color .2s ease;
}

.sbl-09__nav svg,
.sbl-09__fold svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sbl-09__fold svg {
  transition: rotate .3s cubic-bezier(.4,0,.2,1);
}

.sbl-09__txt,
.sbl-09__word {
  opacity: 1;
  transition: opacity .18s ease .12s;
}

.sbl-09:has(#sbl09-c:checked) .sbl-09__txt,
.sbl-09:has(#sbl09-c:checked) .sbl-09__word {
  opacity: 0;
  transition: opacity .18s ease;
}

.sbl-09:has(#sbl09-c:checked) .sbl-09__fold svg {
  rotate: 180deg;
}

.sbl-09__nav a:hover,
.sbl-09__fold:hover {
  color: var(--ink);
  background: color-mix(in oklab,var(--ink) 6%,transparent);
}

.sbl-09__nav a[aria-current="page"] {
  color: var(--accent);
  background: color-mix(in oklab,var(--accent) 12%,transparent);
}

.sbl-09__nav a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sbl-09:has(#sbl09-c:focus-visible) .sbl-09__fold {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sbl-09__fold {
  margin-top: auto;
}

.sbl-09__main {
  padding: 32px;
  overflow-y: auto;
}

.sbl-09__main h1 {
  font: 600 22px/1.2 system-ui,sans-serif;
  margin-bottom: 10px;
}

.sbl-09__main p {
  color: var(--mut);
  font-size: 14px;
  line-height: 1.6;
  max-width: 46ch;
  text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
  .sbl-09,
    .sbl-09 .sbl-09__txt,
    .sbl-09 .sbl-09__word,
    .sbl-09 .sbl-09__fold svg {
    transition: none;
  }
}
```

## JavaScript
```js
/* No JavaScript — the grid track animates 248px→68px; labels fade on a faster, asymmetrically-delayed transition for native-feeling choreography. */
```

How this works

Like demo 02, the collapse animates the shell's own grid track (grid-template-columns:248px 1fr → 68px 1fr) — but this demo is about the choreography. Labels don't just ride along; they get their own faster transition (opacity .18s) with no delay on collapse and a .12s delay on expand. Collapse: text vanishes first, then the rail narrows around the icons. Expand: the rail opens first, then text fades into the prepared space. That asymmetric stagger is how native apps sequence it, and it costs two lines of CSS.

Centering is handled by the link's own grid: grid-template-columns:20px 1fr with justify-content:start becomes effectively icon-only because the label column collapses to 0fr; combined with symmetric padding the icons end up optically centered in the 68px rail with no per-state position hacks. The brand row keeps its logo mark and drops only the wordmark, so the product stays identifiable at any width.

Make it yours

  • The stagger timings (.18s fade, .12s delay) scale with the track duration — keep fade ≈ 60% of track time.
  • Persist the collapsed choice with demo 20's data-state + localStorage pattern; the CSS here doesn't change.
  • Add demo 02's [data-tooltip] pseudo-elements for hover labels in the collapsed state — the two patterns compose.
  • 68px rail: bump to 76px if your icons are 24px — keep at least 22px of breathing room.

Gotchas — read before shipping

  • Never animate width on the aside INSTEAD of the grid track — content reflows twice and the main pane judders.
  • The label needs white-space:nowrap or it wraps mid-collapse and the rail height jumps.
  • Keep the checkbox visually-hidden but focusable — display:none would remove keyboard access to the toggle entirely.

Browser support

ChromeSafariFirefoxEdge
114+17.5+121+114+

Floor set by :has(), oklch(), color-mix(), text-wrap as this demo is written. The core technique itself goes back further — Chrome 107+.

Animatable grid tracks + :has(). Without track animation the collapse still works, it just snaps.

Techniques used in this demo

Search CodeFronts

Loading…