30 CSS Sidebar Layouts
02 / 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

Accessible Admin Panel Sidebar with CSS Tooltips and Icon Collapse

An enterprise admin rail that collapses from 240px of labeled navigation down to a 64px icon strip — and when collapsed, every icon grows a floating tooltip on hover AND keyboard focus, built from a data-tooltip attribute and one pseudo-element. The collapse animates the grid track itself, so main content reflows smoothly with it.

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-02">
  <input type="checkbox" id="sbl02-fold" class="sbl-02__check">
  <aside class="sbl-02__sidebar">
    <label for="sbl02-fold" class="sbl-02__fold" data-tooltip="Expand"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m14 6-6 6 6 6"/></svg><span class="sbl-02__label">Collapse</span></label>
    <nav class="sbl-02__nav" aria-label="Admin">
      <a class="sbl-02__link" href="#" aria-current="page" data-tooltip="Dashboard"><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-02__label">Dashboard</span></a>
      <a class="sbl-02__link" href="#" data-tooltip="Users"><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-02__label">Users</span></a>
      <a class="sbl-02__link" href="#" data-tooltip="Reports"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 20V10m6 10V4m6 16v-7"/></svg><span class="sbl-02__label">Reports</span></a>
      <a class="sbl-02__link" href="#" data-tooltip="Audit log"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 6h13M8 12h13M8 18h13M3.5 6h.01M3.5 12h.01M3.5 18h.01"/></svg><span class="sbl-02__label">Audit log</span></a>
      <a class="sbl-02__link" href="#" data-tooltip="Settings"><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-02__label">Settings</span></a>
    </nav>
  </aside>
  <main class="sbl-02__main"><h1>User management</h1><p>Toggle the chevron — labels fold into a 0fr grid track and tooltips take over.</p></main>
</section>
.sbl-02,
.sbl-02 *,
.sbl-02 *::before,
.sbl-02 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.sbl-02 {
  --panel: oklch(0.16 0.02 275);
  --ink: oklch(0.92 0.005 275);
  --mut: oklch(0.64 0.012 275);
  --line: oklch(0.27 0.02 275);
  --accent: oklch(0.68 0.17 275);
  display: grid;
  grid-template-columns: 240px 1fr;
  height: 100vh;
  height: 100dvh;
  font-family: system-ui,'Segoe UI',sans-serif;
  background: oklch(0.13 0.015 275);
  color: var(--ink);
  transition: grid-template-columns .3s ease;
}

.sbl-02:has(#sbl02-fold:checked) {
  grid-template-columns: 64px 1fr;
}

.sbl-02__check {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.sbl-02__sidebar {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 10px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  overflow: visible;
}

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

.sbl-02__fold {
  margin-bottom: 10px;
  color: var(--ink);
}

.sbl-02__fold svg,
.sbl-02__link svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: rotate .3s ease;
}

.sbl-02__label {
  display: grid;
  grid-template-columns: 1fr;
  overflow: hidden;
  white-space: nowrap;
  transition: grid-template-columns .3s ease,opacity .25s ease;
}

.sbl-02:has(#sbl02-fold:checked) .sbl-02__label {
  grid-template-columns: 0fr;
  opacity: 0;
}

.sbl-02:has(#sbl02-fold:checked) .sbl-02__fold svg {
  rotate: 180deg;
}

.sbl-02__link:hover,
.sbl-02__fold:hover {
  color: var(--ink);
  background: color-mix(in oklab,var(--ink) 7%,transparent);
}

.sbl-02__link[aria-current="page"] {
  color: var(--ink);
  background: color-mix(in oklab,var(--accent) 20%,transparent);
}

.sbl-02__link:focus-visible,
.sbl-02:has(#sbl02-fold:focus-visible) .sbl-02__fold {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sbl-02__fold::after,
.sbl-02__link::after {
  content: attr(data-tooltip);
  position: absolute;
  left: calc(100% + 14px);
  top: 50%;
  translate: -4px -50%;
  padding: 7px 11px;
  border-radius: 8px;
  background: oklch(0.24 0.02 275);
  border: 1px solid var(--line);
  color: var(--ink);
  font: 500 12.5px/1 system-ui,sans-serif;
  white-space: nowrap;
  box-shadow: 0 6px 18px oklch(0 0 0 / .4);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease .15s,translate .2s ease .15s;
  z-index: 5;
}

.sbl-02:has(#sbl02-fold:checked) .sbl-02__link:hover::after,
.sbl-02:has(#sbl02-fold:checked) .sbl-02__link:focus-visible::after,
.sbl-02:has(#sbl02-fold:checked) .sbl-02__fold:hover::after {
  opacity: 1;
  translate: 0 -50%;
}

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

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

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

@media (prefers-reduced-motion: reduce) {
  .sbl-02,
    .sbl-02 .sbl-02__label,
    .sbl-02 .sbl-02__fold svg {
    transition: none;
  }
}
/* No JavaScript — grid-template-columns animates 240px→64px via :has(:checked); labels collapse to a 0fr track; tooltips are [data-tooltip]::after. */
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: Accessible Admin Panel Sidebar with CSS Tooltips and Icon Collapse
Source: https://codefronts.com/layouts/css-sidebar-layouts/accessible-admin-panel-sidebar-with-css-tooltips-and-icon-collapse/

An enterprise admin rail that collapses from 240px of labeled navigation down to a 64px icon strip — and when collapsed, every icon grows a floating tooltip on hover AND keyboard focus, built from a data-tooltip attribute and one pseudo-element. The collapse animates the grid track itself, so main content reflows smoothly with it.
## HTML
```html
<section class="sbl-02">
  <input type="checkbox" id="sbl02-fold" class="sbl-02__check">
  <aside class="sbl-02__sidebar">
    <label for="sbl02-fold" class="sbl-02__fold" data-tooltip="Expand"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m14 6-6 6 6 6"/></svg><span class="sbl-02__label">Collapse</span></label>
    <nav class="sbl-02__nav" aria-label="Admin">
      <a class="sbl-02__link" href="#" aria-current="page" data-tooltip="Dashboard"><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-02__label">Dashboard</span></a>
      <a class="sbl-02__link" href="#" data-tooltip="Users"><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-02__label">Users</span></a>
      <a class="sbl-02__link" href="#" data-tooltip="Reports"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 20V10m6 10V4m6 16v-7"/></svg><span class="sbl-02__label">Reports</span></a>
      <a class="sbl-02__link" href="#" data-tooltip="Audit log"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 6h13M8 12h13M8 18h13M3.5 6h.01M3.5 12h.01M3.5 18h.01"/></svg><span class="sbl-02__label">Audit log</span></a>
      <a class="sbl-02__link" href="#" data-tooltip="Settings"><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-02__label">Settings</span></a>
    </nav>
  </aside>
  <main class="sbl-02__main"><h1>User management</h1><p>Toggle the chevron — labels fold into a 0fr grid track and tooltips take over.</p></main>
</section>
```
## CSS
```css
.sbl-02,
.sbl-02 *,
.sbl-02 *::before,
.sbl-02 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.sbl-02 {
  --panel: oklch(0.16 0.02 275);
  --ink: oklch(0.92 0.005 275);
  --mut: oklch(0.64 0.012 275);
  --line: oklch(0.27 0.02 275);
  --accent: oklch(0.68 0.17 275);
  display: grid;
  grid-template-columns: 240px 1fr;
  height: 100vh;
  height: 100dvh;
  font-family: system-ui,'Segoe UI',sans-serif;
  background: oklch(0.13 0.015 275);
  color: var(--ink);
  transition: grid-template-columns .3s ease;
}

.sbl-02:has(#sbl02-fold:checked) {
  grid-template-columns: 64px 1fr;
}

.sbl-02__check {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.sbl-02__sidebar {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 10px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  overflow: visible;
}

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

.sbl-02__fold {
  margin-bottom: 10px;
  color: var(--ink);
}

.sbl-02__fold svg,
.sbl-02__link svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: rotate .3s ease;
}

.sbl-02__label {
  display: grid;
  grid-template-columns: 1fr;
  overflow: hidden;
  white-space: nowrap;
  transition: grid-template-columns .3s ease,opacity .25s ease;
}

.sbl-02:has(#sbl02-fold:checked) .sbl-02__label {
  grid-template-columns: 0fr;
  opacity: 0;
}

.sbl-02:has(#sbl02-fold:checked) .sbl-02__fold svg {
  rotate: 180deg;
}

.sbl-02__link:hover,
.sbl-02__fold:hover {
  color: var(--ink);
  background: color-mix(in oklab,var(--ink) 7%,transparent);
}

.sbl-02__link[aria-current="page"] {
  color: var(--ink);
  background: color-mix(in oklab,var(--accent) 20%,transparent);
}

.sbl-02__link:focus-visible,
.sbl-02:has(#sbl02-fold:focus-visible) .sbl-02__fold {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sbl-02__fold::after,
.sbl-02__link::after {
  content: attr(data-tooltip);
  position: absolute;
  left: calc(100% + 14px);
  top: 50%;
  translate: -4px -50%;
  padding: 7px 11px;
  border-radius: 8px;
  background: oklch(0.24 0.02 275);
  border: 1px solid var(--line);
  color: var(--ink);
  font: 500 12.5px/1 system-ui,sans-serif;
  white-space: nowrap;
  box-shadow: 0 6px 18px oklch(0 0 0 / .4);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease .15s,translate .2s ease .15s;
  z-index: 5;
}

.sbl-02:has(#sbl02-fold:checked) .sbl-02__link:hover::after,
.sbl-02:has(#sbl02-fold:checked) .sbl-02__link:focus-visible::after,
.sbl-02:has(#sbl02-fold:checked) .sbl-02__fold:hover::after {
  opacity: 1;
  translate: 0 -50%;
}

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

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

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

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

## JavaScript
```js
/* No JavaScript — grid-template-columns animates 240px→64px via :has(:checked); labels collapse to a 0fr track; tooltips are [data-tooltip]::after. */
```

How this works

The shell is display:grid; grid-template-columns:240px 1fr, and the collapse is literally grid-template-columns:64px 1fr on .sbl-02:has(#sbl02-fold:checked) — grid tracks are animatable in every modern engine, so one transition moves the sidebar edge and reflows the content pane in a single composited motion. Inside each link, the label sits in its own grid: grid-template-columns:auto 1fr collapsing to auto 0fr with overflow:hidden on the label cell. Animating to 0fr (not width:0) is the modern trick — the browser interpolates the fraction, so text slides away instead of wrapping or snapping.

Tooltips are the [data-tooltip]::after pattern: content:attr(data-tooltip) renders the attribute text in a floating pill positioned off the link's right edge with translate. They're gated to the collapsed state only (.sbl-02:has(:checked) .sbl-02__link:hover::after) and fire on :focus-visible too, so keyboard users get the same affordance. Because the tooltip is a pseudo-element of the real link, screen readers still read the visually-hidden label — the tooltip is purely visual redundancy.

Make it yours

  • Collapsed width: 64px fits 20px icons with comfortable 44px hit targets; 72px if you add a badge column.
  • Tooltip delay: add transition-delay:.3s on the ::after opacity so tooltips don't strobe while the cursor travels the rail.
  • Auto-collapse on small screens by moving the 64px template into a @media (max-width:900px) block — the checkbox then becomes a desktop-only preference.
  • Swap the chevron for a hamburger by editing the two ::before/::after transforms on the fold button.

Gotchas — read before shipping

  • Pseudo-element tooltips can't cross a parent with overflow:hidden — keep overflow on the label cell, never on the link or the aside, or tooltips get clipped.
  • Grid track animation interpolates between two fixed values — auto as an endpoint won't animate; use explicit px on both states.
  • Icon-only nav without accessible names is a WCAG failure: the label span stays in the DOM (clipped, not display:none) so the link's name never disappears.

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 (Chrome 107, Safari 16) and :has() set the floor. Fallback: the layout still collapses, just without the tween.

Techniques used in this demo

Search CodeFronts

Loading…