30 Tailwind CSS Sidebar Layouts
19 / 30

All 30 in 30 Tailwind CSS Sidebar Layouts

  1. 01Tailwind SaaS Dashboard Sidebar with Native Dark Mode Switch
  2. 02Tailwind Collapsible Admin Sidebar with Icon Tooltips
  3. 03Tailwind Documentation Sidebar with Multi-Level :target Tree
  4. 04Tailwind Responsive Sidebar to Bottom Navigation Switch Layout
  5. 05Tailwind Analytics Sidebar with CSS Subgrid Column Alignment
  6. 06Tailwind Animated Collapsible Sidebar with Icon-Only Mode
  7. 07Tailwind Sticky Sidebar Layout with Scroll-Driven Progress Bar
  8. 08Tailwind Pure CSS Collapsible Sidebar Drawer without JavaScript
  9. 09Tailwind Fixed Sidebar Layout with Independently Scrolling Content
  10. 10Tailwind Off-Canvas Navigation Drawer with the Popover API
  11. 11Tailwind Right-Aligned Sidebar Layout for Inspector Panels
  12. 12Tailwind Two-Pane Webmail Layout with List and Reading Pane
  13. 13Tailwind Dual Sidebar App Shell with Left Nav and Context Panel
  14. 14Tailwind Mini Icon Rail Sidebar with Anchor-Positioned Active Pill
  15. 15Tailwind E-Commerce Filter Sidebar with Native Details Accordion
  16. 16Tailwind Floating Glassmorphism Sidebar with Gradient Hairline
  17. 17Tailwind Sidebar Menu with Pinned User Profile Footer
  18. 18Tailwind Push-Content Sidebar Drawer with GPU Transitions
  19. 19Tailwind Off-Canvas Cart Overlay with Blurred Backdrop Scrim
  20. 20Tailwind Sidebar with Persistent Collapsed State in localStorage
  21. 21Tailwind Sidebar with Sticky Search Bar Inside the Rail
  22. 22Tailwind Section-Grouped Sidebar Navigation with Header Labels
  23. 23Tailwind Sliding Active Indicator Sidebar with CSS :target
  24. 24Tailwind Multi-Level Nested Tree Sidebar with Details Branches
  25. 25Tailwind Tabbed Sidebar with Radio-Driven Panel Switching
  26. 26Tailwind Onboarding Wizard Sidebar with Step Progress Tracking
  27. 27Tailwind Resizable Sidebar Layout Using the CSS Resize Property
  28. 28Tailwind Three-Pane Workspace Shell with Icon Rail and List
  29. 29Tailwind Adaptive Sidebar Layout Using CSS Container Queries
  30. 30Tailwind Frosted Glass Floating Sidebar with Animated Aurora
Pure TailwindMIT licensed

Tailwind Off-Canvas Cart Overlay with Blurred Backdrop Scrim

The modal-grade overlay drawer: content dims and blurs behind a scrim, the panel lifts on a shadow that fades in with the slide, and pointer-events discipline keeps the dimmed page genuinely inert. A cart, because that is the pattern's home.

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="tsl-19 relative w-full h-svh min-h-svh grid grid-rows-[auto_1fr] overflow-hidden font-tsl19-sans bg-tsl19-bg text-tsl19-ink">
  <input type="checkbox" id="tsl19-o" class="sr-only peer">
  <header class="flex items-center justify-between h-14 px-5 bg-white border-b border-tsl19-line text-[15px] font-bold">
    <strong>Alpine Supply Co.</strong>
    <label for="tsl19-o" class="inline-flex items-center gap-2.5 min-h-11 px-3.5 rounded-[10px] border border-tsl19-line text-[13px] font-semibold cursor-pointer transition-colors duration-200 hover:bg-tsl19-hover"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-[17px] h-[17px] fill-none stroke-current stroke-[1.9] [stroke-linecap:round] [stroke-linejoin:round]"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/></svg>Cart &middot; 2</label>
  </header>
  <main class="p-[26px] overflow-y-auto [scrollbar-gutter:stable]">
    <h1 class="mb-[18px] text-[21px] font-bold leading-tight">New arrivals</h1>
    <div class="grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3.5">
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
    </div>
  </main>
  <label for="tsl19-o" aria-hidden="true" class="tsl-19-scrim absolute inset-0 z-[3] bg-[oklch(0_0_0/0.45)] backdrop-blur-[4px] opacity-0 pointer-events-none transition-opacity duration-300 motion-reduce:transition-none"></label>
  <aside aria-label="Shopping cart" class="tsl-19-cart absolute inset-y-0 right-0 z-[4] flex flex-col w-[min(340px,92vw)] p-[18px] bg-white border-l border-tsl19-line translate-x-full transition-[translate,box-shadow] duration-[320ms] ease-[cubic-bezier(.4,0,.2,1)] motion-reduce:transition-none">
    <div class="flex items-center justify-between pb-4">
      <h2 class="text-base font-bold">Your cart</h2>
      <label for="tsl19-o" aria-label="Close cart" class="grid place-items-center w-11 h-11 rounded-[9px] text-tsl19-mut cursor-pointer transition-colors duration-200 hover:text-tsl19-ink hover:bg-tsl19-hover"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-[17px] h-[17px] fill-none stroke-current stroke-[1.9] [stroke-linecap:round]"><path d="M6 6l12 12M18 6 6 18"/></svg></label>
    </div>
    <div class="grid grid-cols-[auto_1fr_auto] gap-3 items-center py-3 border-t border-tsl19-line"><span aria-hidden="true" class="w-[52px] h-[52px] rounded-[10px] bg-[linear-gradient(150deg,oklch(0.9_0.012_145),oklch(0.84_0.018_145))]"></span><span><strong class="block text-[13.5px] font-semibold leading-snug">Ridge shell jacket</strong><small class="text-xs leading-snug text-tsl19-mut">Moss &middot; M</small></span><data class="text-[13.5px] font-semibold tabular-nums">$168</data></div>
    <div class="grid grid-cols-[auto_1fr_auto] gap-3 items-center py-3 border-t border-tsl19-line"><span aria-hidden="true" class="w-[52px] h-[52px] rounded-[10px] bg-[linear-gradient(150deg,oklch(0.9_0.012_145),oklch(0.84_0.018_145))]"></span><span><strong class="block text-[13.5px] font-semibold leading-snug">Trail merino crew</strong><small class="text-xs leading-snug text-tsl19-mut">Ash &middot; L</small></span><data class="text-[13.5px] font-semibold tabular-nums">$74</data></div>
    <div class="mt-auto grid grid-cols-[1fr_auto] items-center gap-3.5 pt-4 border-t border-tsl19-line text-sm font-medium text-tsl19-mut">
      <span>Subtotal</span><data class="text-[13.5px] font-semibold tabular-nums text-tsl19-ink">$242</data>
      <button type="button" class="col-span-full min-h-12 rounded-[11px] border-0 bg-tsl19-accent text-white text-sm font-bold cursor-pointer transition-[filter] duration-200 hover:brightness-110 focus-visible:outline-2 focus-visible:outline-tsl19-accent focus-visible:outline-offset-2">Checkout</button>
    </div>
  </aside>
</section>
@import "tailwindcss";

@theme {
  --color-tsl19-bg: #f8faf7;
  --color-tsl19-bg: oklch(0.975 0.004 120);
  --color-tsl19-ink: #383f3a;
  --color-tsl19-ink: oklch(0.26 0.015 145);
  --color-tsl19-mut: #767e78;
  --color-tsl19-mut: oklch(0.52 0.012 145);
  --color-tsl19-line: #e0e5e1;
  --color-tsl19-line: oklch(0.9 0.008 145);
  --color-tsl19-accent: #2f7a52;
  --color-tsl19-accent: oklch(0.45 0.12 150);
  --color-tsl19-hover: rgb(56 63 58 / 0.05);
  --color-tsl19-hover: color-mix(in oklab, oklch(0.26 0.015 145) 5%, transparent);
  --font-tsl19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}

.tsl-19 {
  width: 100%;
  height: 100svh;
  min-height: 100svh;
  color-scheme: light;
}
/* STATE — opacity transitions, pointer-events flips instantly, so a
   half-faded scrim is never clickable. */

#tsl19-o:checked ~ .tsl-19-scrim {
  opacity: 1;
  pointer-events: auto;
}

#tsl19-o:checked ~ .tsl-19-cart {
  translate: 0;
  box-shadow: -16px 0 48px oklch(0 0 0 / 0.18);
}

#tsl19-o:focus-visible ~ header label[for="tsl19-o"] {
  outline: 2px solid var(--color-tsl19-accent);
  outline-offset: 2px;
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tsl19-bg: #f8faf7;
  --color-tsl19-bg: oklch(0.975 0.004 120);
  --color-tsl19-ink: #383f3a;
  --color-tsl19-ink: oklch(0.26 0.015 145);
  --color-tsl19-mut: #767e78;
  --color-tsl19-mut: oklch(0.52 0.012 145);
  --color-tsl19-line: #e0e5e1;
  --color-tsl19-line: oklch(0.9 0.008 145);
  --color-tsl19-accent: #2f7a52;
  --color-tsl19-accent: oklch(0.45 0.12 150);
  --color-tsl19-hover: rgb(56 63 58 / 0.05);
  --color-tsl19-hover: color-mix(in oklab, oklch(0.26 0.015 145) 5%, transparent);
  --font-tsl19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}

.tsl-19 {
  width: 100%;
  height: 100svh;
  min-height: 100svh;
  color-scheme: light;
}
/* STATE — opacity transitions, pointer-events flips instantly, so a
   half-faded scrim is never clickable. */

#tsl19-o:checked ~ .tsl-19-scrim {
  opacity: 1;
  pointer-events: auto;
}

#tsl19-o:checked ~ .tsl-19-cart {
  translate: 0;
  box-shadow: -16px 0 48px oklch(0 0 0 / 0.18);
}

#tsl19-o:focus-visible ~ header label[for="tsl19-o"] {
  outline: 2px solid var(--color-tsl19-accent);
  outline-offset: 2px;
}
3Fonts used by this demooptional — skip if you have your own type stack
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • Pairing opacity with pointer-events as two has-checked: utilities on the same element is the strongest argument for variants in this whole collection: the bug this pattern usually ships with (an invisible scrim that still eats clicks) becomes visible as a missing class.
  • UI change from the CSS original: the close control is 44px rather than 34px, the checkout button is min-h-12, and totals use tabular-nums so quantities and prices stay aligned as the cart changes.
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 demo 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: Tailwind Off-Canvas Cart Overlay with Blurred Backdrop Scrim
Source: https://codefronts.com/layouts/tailwind-css-sidebar-layouts/tailwind-off-canvas-cart-overlay-blurred-backdrop/

The modal-grade overlay drawer: content dims and blurs behind a scrim, the panel lifts on a shadow that fades in with the slide, and pointer-events discipline keeps the dimmed page genuinely inert. A cart, because that is the pattern's home.
## HTML
```html
<section class="tsl-19 relative w-full h-svh min-h-svh grid grid-rows-[auto_1fr] overflow-hidden font-tsl19-sans bg-tsl19-bg text-tsl19-ink">
  <input type="checkbox" id="tsl19-o" class="sr-only peer">
  <header class="flex items-center justify-between h-14 px-5 bg-white border-b border-tsl19-line text-[15px] font-bold">
    <strong>Alpine Supply Co.</strong>
    <label for="tsl19-o" class="inline-flex items-center gap-2.5 min-h-11 px-3.5 rounded-[10px] border border-tsl19-line text-[13px] font-semibold cursor-pointer transition-colors duration-200 hover:bg-tsl19-hover"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-[17px] h-[17px] fill-none stroke-current stroke-[1.9] [stroke-linecap:round] [stroke-linejoin:round]"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/></svg>Cart &middot; 2</label>
  </header>
  <main class="p-[26px] overflow-y-auto [scrollbar-gutter:stable]">
    <h1 class="mb-[18px] text-[21px] font-bold leading-tight">New arrivals</h1>
    <div class="grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3.5">
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
      <div class="aspect-[3/4] rounded-xl bg-[linear-gradient(150deg,oklch(0.93_0.01_145),oklch(0.87_0.015_145))]"></div>
    </div>
  </main>
  <label for="tsl19-o" aria-hidden="true" class="tsl-19-scrim absolute inset-0 z-[3] bg-[oklch(0_0_0/0.45)] backdrop-blur-[4px] opacity-0 pointer-events-none transition-opacity duration-300 motion-reduce:transition-none"></label>
  <aside aria-label="Shopping cart" class="tsl-19-cart absolute inset-y-0 right-0 z-[4] flex flex-col w-[min(340px,92vw)] p-[18px] bg-white border-l border-tsl19-line translate-x-full transition-[translate,box-shadow] duration-[320ms] ease-[cubic-bezier(.4,0,.2,1)] motion-reduce:transition-none">
    <div class="flex items-center justify-between pb-4">
      <h2 class="text-base font-bold">Your cart</h2>
      <label for="tsl19-o" aria-label="Close cart" class="grid place-items-center w-11 h-11 rounded-[9px] text-tsl19-mut cursor-pointer transition-colors duration-200 hover:text-tsl19-ink hover:bg-tsl19-hover"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-[17px] h-[17px] fill-none stroke-current stroke-[1.9] [stroke-linecap:round]"><path d="M6 6l12 12M18 6 6 18"/></svg></label>
    </div>
    <div class="grid grid-cols-[auto_1fr_auto] gap-3 items-center py-3 border-t border-tsl19-line"><span aria-hidden="true" class="w-[52px] h-[52px] rounded-[10px] bg-[linear-gradient(150deg,oklch(0.9_0.012_145),oklch(0.84_0.018_145))]"></span><span><strong class="block text-[13.5px] font-semibold leading-snug">Ridge shell jacket</strong><small class="text-xs leading-snug text-tsl19-mut">Moss &middot; M</small></span><data class="text-[13.5px] font-semibold tabular-nums">$168</data></div>
    <div class="grid grid-cols-[auto_1fr_auto] gap-3 items-center py-3 border-t border-tsl19-line"><span aria-hidden="true" class="w-[52px] h-[52px] rounded-[10px] bg-[linear-gradient(150deg,oklch(0.9_0.012_145),oklch(0.84_0.018_145))]"></span><span><strong class="block text-[13.5px] font-semibold leading-snug">Trail merino crew</strong><small class="text-xs leading-snug text-tsl19-mut">Ash &middot; L</small></span><data class="text-[13.5px] font-semibold tabular-nums">$74</data></div>
    <div class="mt-auto grid grid-cols-[1fr_auto] items-center gap-3.5 pt-4 border-t border-tsl19-line text-sm font-medium text-tsl19-mut">
      <span>Subtotal</span><data class="text-[13.5px] font-semibold tabular-nums text-tsl19-ink">$242</data>
      <button type="button" class="col-span-full min-h-12 rounded-[11px] border-0 bg-tsl19-accent text-white text-sm font-bold cursor-pointer transition-[filter] duration-200 hover:brightness-110 focus-visible:outline-2 focus-visible:outline-tsl19-accent focus-visible:outline-offset-2">Checkout</button>
    </div>
  </aside>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tsl19-bg: #f8faf7;
  --color-tsl19-bg: oklch(0.975 0.004 120);
  --color-tsl19-ink: #383f3a;
  --color-tsl19-ink: oklch(0.26 0.015 145);
  --color-tsl19-mut: #767e78;
  --color-tsl19-mut: oklch(0.52 0.012 145);
  --color-tsl19-line: #e0e5e1;
  --color-tsl19-line: oklch(0.9 0.008 145);
  --color-tsl19-accent: #2f7a52;
  --color-tsl19-accent: oklch(0.45 0.12 150);
  --color-tsl19-hover: rgb(56 63 58 / 0.05);
  --color-tsl19-hover: color-mix(in oklab, oklch(0.26 0.015 145) 5%, transparent);
  --font-tsl19-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}

.tsl-19 {
  width: 100%;
  height: 100svh;
  min-height: 100svh;
  color-scheme: light;
}
/* STATE — opacity transitions, pointer-events flips instantly, so a
   half-faded scrim is never clickable. */

#tsl19-o:checked ~ .tsl-19-scrim {
  opacity: 1;
  pointer-events: auto;
}

#tsl19-o:checked ~ .tsl-19-cart {
  translate: 0;
  box-shadow: -16px 0 48px oklch(0 0 0 / 0.18);
}

#tsl19-o:focus-visible ~ header label[for="tsl19-o"] {
  outline: 2px solid var(--color-tsl19-accent);
  outline-offset: 2px;
}
```

How this works

Two properties carry the whole scrim. opacity transitions (never display, which cannot tween) and pointer-events flips instantly, so a half-faded scrim is never clickable. Both states sit on one element as a has-checked: pair, which is the clearest possible statement of 'resting' versus 'open'.

Right-hand slide is the convention for carts and settings, as left is for navigation. The drawer moves on translate-x only; the shadow is a second animated property on the same 320ms curve.

Make it yours

  • Real modality in six lines: swap the aside for <dialog> + showModal(), or use demo 10's popover — both bring focus trapping.
  • Blur strength: 4px hints, 12px insists. Full-viewport blur is expensive; test on integrated graphics.
  • Curtain choreography: add has-checked:delay-[80ms] to the drawer so the scrim starts fading first.

Gotchas — read before shipping

  • Pure-CSS overlays do NOT trap focus — keyboard users can tab into the dimmed page. Fine for a demo, not for checkout.
  • A full-viewport backdrop-blur is the most expensive effect in this collection. Consider dropping the blur under prefers-reduced-transparency.
  • pointer-events-none on the RESTING scrim is mandatory; an invisible scrim eating every click is a classic shipped bug.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

:has() and backdrop-filter are both Baseline; where backdrop-filter is missing the dim survives on its own.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Search CodeFronts

Loading…