09 / 30
All 30 in 30 Tailwind CSS Sidebar Layouts
- 01Tailwind SaaS Dashboard Sidebar with Native Dark Mode Switch
- 02Tailwind Collapsible Admin Sidebar with Icon Tooltips
- 03Tailwind Documentation Sidebar with Multi-Level :target Tree
- 04Tailwind Responsive Sidebar to Bottom Navigation Switch Layout
- 05Tailwind Analytics Sidebar with CSS Subgrid Column Alignment
- 06Tailwind Animated Collapsible Sidebar with Icon-Only Mode
- 07Tailwind Sticky Sidebar Layout with Scroll-Driven Progress Bar
- 08Tailwind Pure CSS Collapsible Sidebar Drawer without JavaScript
- 09Tailwind Fixed Sidebar Layout with Independently Scrolling Content
- 10Tailwind Off-Canvas Navigation Drawer with the Popover API
- 11Tailwind Right-Aligned Sidebar Layout for Inspector Panels
- 12Tailwind Two-Pane Webmail Layout with List and Reading Pane
- 13Tailwind Dual Sidebar App Shell with Left Nav and Context Panel
- 14Tailwind Mini Icon Rail Sidebar with Anchor-Positioned Active Pill
- 15Tailwind E-Commerce Filter Sidebar with Native Details Accordion
- 16Tailwind Floating Glassmorphism Sidebar with Gradient Hairline
- 17Tailwind Sidebar Menu with Pinned User Profile Footer
- 18Tailwind Push-Content Sidebar Drawer with GPU Transitions
- 19Tailwind Off-Canvas Cart Overlay with Blurred Backdrop Scrim
- 20Tailwind Sidebar with Persistent Collapsed State in localStorage
- 21Tailwind Sidebar with Sticky Search Bar Inside the Rail
- 22Tailwind Section-Grouped Sidebar Navigation with Header Labels
- 23Tailwind Sliding Active Indicator Sidebar with CSS :target
- 24Tailwind Multi-Level Nested Tree Sidebar with Details Branches
- 25Tailwind Tabbed Sidebar with Radio-Driven Panel Switching
- 26Tailwind Onboarding Wizard Sidebar with Step Progress Tracking
- 27Tailwind Resizable Sidebar Layout Using the CSS Resize Property
- 28Tailwind Three-Pane Workspace Shell with Icon Rail and List
- 29Tailwind Adaptive Sidebar Layout Using CSS Container Queries
- 30Tailwind Frosted Glass Floating Sidebar with Animated Aurora
Tailwind Fixed Sidebar Layout with Independently Scrolling Content
The foundational app shell every dashboard starts from — locked rail, independently scrolling main pane — built as a height-constrained grid rather than position:fixed plus a magic margin. Each pane owns its overflow, so nothing overlaps and the whole thing nests inside any container.
Mosaic by Cruip: a complete Tailwind admin dashboard template in HTML, React, Next.js and Vue · $69
Cruip · Mosaic by Cruip · Affiliate link
The code
<section class="tsl-09 w-full h-svh min-h-svh grid grid-cols-[260px_1fr] font-tsl09-sans bg-tsl09-bg text-tsl09-ink">
<aside aria-label="Workspace" class="flex flex-col bg-tsl09-panel border-r border-tsl09-line px-3 py-5 overflow-y-auto overscroll-contain [scrollbar-width:thin] [scrollbar-color:var(--color-tsl09-line)_transparent]">
<div class="flex items-center gap-2.5 px-2.5 pt-0.5 pb-[18px] text-[15px] font-bold tracking-tight"><span aria-hidden="true" class="w-6 h-6 rounded-[7px] bg-[conic-gradient(from_45deg,var(--color-tsl09-accent),oklch(0.6_0.15_260))]"></span>Ledgerly</div>
<nav class="flex flex-col gap-0.5">
<a href="#" aria-current="page" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover aria-[current=page]:text-tsl09-accent aria-[current=page]:bg-tsl09-tint focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Overview</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Transactions</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Invoices</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Recurring</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Vendors</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Categories</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Receipts</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Tax reports</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Bank feeds</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Rules</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Integrations</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Team</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Settings</a>
</nav>
</aside>
<main class="p-8 overflow-y-auto overscroll-contain [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Overview</h1>
<p class="max-w-[52ch] mb-6 text-sm leading-relaxed text-tsl09-mut text-pretty">Both panes scroll independently. The sidebar nav is intentionally long — scroll it, then scroll this pane; neither moves the other.</p>
<div class="grid gap-4">
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
</div>
</main>
</section><section class="tsl-09 w-full h-svh min-h-svh grid grid-cols-[260px_1fr] font-tsl09-sans bg-tsl09-bg text-tsl09-ink">
<aside aria-label="Workspace" class="flex flex-col bg-tsl09-panel border-r border-tsl09-line px-3 py-5 overflow-y-auto overscroll-contain [scrollbar-width:thin] [scrollbar-color:var(--color-tsl09-line)_transparent]">
<div class="flex items-center gap-2.5 px-2.5 pt-0.5 pb-[18px] text-[15px] font-bold tracking-tight"><span aria-hidden="true" class="w-6 h-6 rounded-[7px] bg-[conic-gradient(from_45deg,var(--color-tsl09-accent),oklch(0.6_0.15_260))]"></span>Ledgerly</div>
<nav class="flex flex-col gap-0.5">
<a href="#" aria-current="page" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover aria-[current=page]:text-tsl09-accent aria-[current=page]:bg-tsl09-tint focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Overview</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Transactions</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Invoices</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Recurring</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Vendors</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Categories</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Receipts</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Tax reports</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Bank feeds</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Rules</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Integrations</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Team</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Settings</a>
</nav>
</aside>
<main class="p-8 overflow-y-auto overscroll-contain [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Overview</h1>
<p class="max-w-[52ch] mb-6 text-sm leading-relaxed text-tsl09-mut text-pretty">Both panes scroll independently. The sidebar nav is intentionally long — scroll it, then scroll this pane; neither moves the other.</p>
<div class="grid gap-4">
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
</div>
</main>
</section>@import "tailwindcss";
@theme {
--color-tsl09-bg: #111518;
--color-tsl09-bg: oklch(0.13 0.012 235);
--color-tsl09-panel: #191d21;
--color-tsl09-panel: oklch(0.17 0.015 235);
--color-tsl09-ink: #e9ebed;
--color-tsl09-ink: oklch(0.93 0.005 235);
--color-tsl09-mut: #90959b;
--color-tsl09-mut: oklch(0.63 0.012 235);
--color-tsl09-line: #383d42;
--color-tsl09-line: oklch(0.28 0.015 235);
--color-tsl09-accent: #5cc4dd;
--color-tsl09-accent: oklch(0.72 0.13 210);
--color-tsl09-hover: rgb(233 235 237 / 0.06);
--color-tsl09-hover: color-mix(in oklab, oklch(0.93 0.005 235) 6%, transparent);
--color-tsl09-tint: rgb(92 196 221 / 0.17);
--color-tsl09-tint: color-mix(in oklab, oklch(0.72 0.13 210) 17%, transparent);
--font-tsl09-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-09 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}@import "tailwindcss";
@theme {
--color-tsl09-bg: #111518;
--color-tsl09-bg: oklch(0.13 0.012 235);
--color-tsl09-panel: #191d21;
--color-tsl09-panel: oklch(0.17 0.015 235);
--color-tsl09-ink: #e9ebed;
--color-tsl09-ink: oklch(0.93 0.005 235);
--color-tsl09-mut: #90959b;
--color-tsl09-mut: oklch(0.63 0.012 235);
--color-tsl09-line: #383d42;
--color-tsl09-line: oklch(0.28 0.015 235);
--color-tsl09-accent: #5cc4dd;
--color-tsl09-accent: oklch(0.72 0.13 210);
--color-tsl09-hover: rgb(233 235 237 / 0.06);
--color-tsl09-hover: color-mix(in oklab, oklch(0.93 0.005 235) 6%, transparent);
--color-tsl09-tint: rgb(92 196 221 / 0.17);
--color-tsl09-tint: color-mix(in oklab, oklch(0.72 0.13 210) 17%, transparent);
--font-tsl09-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-09 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<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.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tsl09-bg: #111518;
--color-tsl09-bg: oklch(0.13 0.012 235);
--color-tsl09-panel: #191d21;
--color-tsl09-panel: oklch(0.17 0.015 235);
--color-tsl09-ink: #e9ebed;
--color-tsl09-ink: oklch(0.93 0.005 235);
--color-tsl09-mut: #90959b;
--color-tsl09-mut: oklch(0.63 0.012 235);
--color-tsl09-line: #383d42;
--color-tsl09-line: oklch(0.28 0.015 235);
--color-tsl09-accent: #5cc4dd;
--color-tsl09-accent: oklch(0.72 0.13 210);
--color-tsl09-hover: rgb(233 235 237 / 0.06);
--color-tsl09-hover: color-mix(in oklab, oklch(0.93 0.005 235) 6%, transparent);
--color-tsl09-tint: rgb(92 196 221 / 0.17);
--color-tsl09-tint: color-mix(in oklab, oklch(0.72 0.13 210) 17%, transparent);
--font-tsl09-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-09 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}@import "tailwindcss";
@theme {
--color-tsl09-bg: #111518;
--color-tsl09-bg: oklch(0.13 0.012 235);
--color-tsl09-panel: #191d21;
--color-tsl09-panel: oklch(0.17 0.015 235);
--color-tsl09-ink: #e9ebed;
--color-tsl09-ink: oklch(0.93 0.005 235);
--color-tsl09-mut: #90959b;
--color-tsl09-mut: oklch(0.63 0.012 235);
--color-tsl09-line: #383d42;
--color-tsl09-line: oklch(0.28 0.015 235);
--color-tsl09-accent: #5cc4dd;
--color-tsl09-accent: oklch(0.72 0.13 210);
--color-tsl09-hover: rgb(233 235 237 / 0.06);
--color-tsl09-hover: color-mix(in oklab, oklch(0.93 0.005 235) 6%, transparent);
--color-tsl09-tint: rgb(92 196 221 / 0.17);
--color-tsl09-tint: color-mix(in oklab, oklch(0.72 0.13 210) 17%, transparent);
--font-tsl09-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-09 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}<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">
<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.
- Nothing here needed to stay CSS — even
scrollbar-colorandscrollbar-gutterport cleanly as arbitrary properties. That makes this the collection's purest utility demo, and a good baseline for judging the others. - UI change from the CSS original: nav rows went from 10px padding to
min-h-11, the shell usesh-svhinstead of the100vh/100dvhpair (svh is the stable small viewport, which is what an app shell wants), andoverscroll-containnow applies to the main pane too, not just the rail.
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 Fixed Sidebar Layout with Independently Scrolling Content
Source: https://codefronts.com/layouts/tailwind-css-sidebar-layouts/tailwind-fixed-sidebar-independently-scrolling-content/
The foundational app shell every dashboard starts from — locked rail, independently scrolling main pane — built as a height-constrained grid rather than position:fixed plus a magic margin. Each pane owns its overflow, so nothing overlaps and the whole thing nests inside any container.
## HTML
```html
<section class="tsl-09 w-full h-svh min-h-svh grid grid-cols-[260px_1fr] font-tsl09-sans bg-tsl09-bg text-tsl09-ink">
<aside aria-label="Workspace" class="flex flex-col bg-tsl09-panel border-r border-tsl09-line px-3 py-5 overflow-y-auto overscroll-contain [scrollbar-width:thin] [scrollbar-color:var(--color-tsl09-line)_transparent]">
<div class="flex items-center gap-2.5 px-2.5 pt-0.5 pb-[18px] text-[15px] font-bold tracking-tight"><span aria-hidden="true" class="w-6 h-6 rounded-[7px] bg-[conic-gradient(from_45deg,var(--color-tsl09-accent),oklch(0.6_0.15_260))]"></span>Ledgerly</div>
<nav class="flex flex-col gap-0.5">
<a href="#" aria-current="page" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover aria-[current=page]:text-tsl09-accent aria-[current=page]:bg-tsl09-tint focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Overview</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Transactions</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Invoices</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Recurring</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Vendors</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Categories</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Receipts</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Tax reports</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Bank feeds</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Rules</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Integrations</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Team</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Settings</a>
</nav>
</aside>
<main class="p-8 overflow-y-auto overscroll-contain [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Overview</h1>
<p class="max-w-[52ch] mb-6 text-sm leading-relaxed text-tsl09-mut text-pretty">Both panes scroll independently. The sidebar nav is intentionally long — scroll it, then scroll this pane; neither moves the other.</p>
<div class="grid gap-4">
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
</div>
</main>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsl09-bg: #111518;
--color-tsl09-bg: oklch(0.13 0.012 235);
--color-tsl09-panel: #191d21;
--color-tsl09-panel: oklch(0.17 0.015 235);
--color-tsl09-ink: #e9ebed;
--color-tsl09-ink: oklch(0.93 0.005 235);
--color-tsl09-mut: #90959b;
--color-tsl09-mut: oklch(0.63 0.012 235);
--color-tsl09-line: #383d42;
--color-tsl09-line: oklch(0.28 0.015 235);
--color-tsl09-accent: #5cc4dd;
--color-tsl09-accent: oklch(0.72 0.13 210);
--color-tsl09-hover: rgb(233 235 237 / 0.06);
--color-tsl09-hover: color-mix(in oklab, oklch(0.93 0.005 235) 6%, transparent);
--color-tsl09-tint: rgb(92 196 221 / 0.17);
--color-tsl09-tint: color-mix(in oklab, oklch(0.72 0.13 210) 17%, transparent);
--font-tsl09-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-09 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}
```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 Fixed Sidebar Layout with Independently Scrolling Content
Source: https://codefronts.com/layouts/tailwind-css-sidebar-layouts/tailwind-fixed-sidebar-independently-scrolling-content/
The foundational app shell every dashboard starts from — locked rail, independently scrolling main pane — built as a height-constrained grid rather than position:fixed plus a magic margin. Each pane owns its overflow, so nothing overlaps and the whole thing nests inside any container.
## HTML
```html
<section class="tsl-09 w-full h-svh min-h-svh grid grid-cols-[260px_1fr] font-tsl09-sans bg-tsl09-bg text-tsl09-ink">
<aside aria-label="Workspace" class="flex flex-col bg-tsl09-panel border-r border-tsl09-line px-3 py-5 overflow-y-auto overscroll-contain [scrollbar-width:thin] [scrollbar-color:var(--color-tsl09-line)_transparent]">
<div class="flex items-center gap-2.5 px-2.5 pt-0.5 pb-[18px] text-[15px] font-bold tracking-tight"><span aria-hidden="true" class="w-6 h-6 rounded-[7px] bg-[conic-gradient(from_45deg,var(--color-tsl09-accent),oklch(0.6_0.15_260))]"></span>Ledgerly</div>
<nav class="flex flex-col gap-0.5">
<a href="#" aria-current="page" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover aria-[current=page]:text-tsl09-accent aria-[current=page]:bg-tsl09-tint focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Overview</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Transactions</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Invoices</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Recurring</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Vendors</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Categories</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Receipts</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Tax reports</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Bank feeds</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Rules</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Integrations</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Team</a>
<a href="#" class="flex items-center min-h-11 px-3.5 rounded-[9px] text-[13.5px] font-medium text-tsl09-mut no-underline transition-colors duration-[180ms] hover:text-tsl09-ink hover:bg-tsl09-hover focus-visible:outline-2 focus-visible:outline-tsl09-accent focus-visible:outline-offset-2">Settings</a>
</nav>
</aside>
<main class="p-8 overflow-y-auto overscroll-contain [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Overview</h1>
<p class="max-w-[52ch] mb-6 text-sm leading-relaxed text-tsl09-mut text-pretty">Both panes scroll independently. The sidebar nav is intentionally long — scroll it, then scroll this pane; neither moves the other.</p>
<div class="grid gap-4">
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
<div class="h-[130px] rounded-2xl bg-tsl09-panel border border-tsl09-line"></div>
</div>
</main>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsl09-bg: #111518;
--color-tsl09-bg: oklch(0.13 0.012 235);
--color-tsl09-panel: #191d21;
--color-tsl09-panel: oklch(0.17 0.015 235);
--color-tsl09-ink: #e9ebed;
--color-tsl09-ink: oklch(0.93 0.005 235);
--color-tsl09-mut: #90959b;
--color-tsl09-mut: oklch(0.63 0.012 235);
--color-tsl09-line: #383d42;
--color-tsl09-line: oklch(0.28 0.015 235);
--color-tsl09-accent: #5cc4dd;
--color-tsl09-accent: oklch(0.72 0.13 210);
--color-tsl09-hover: rgb(233 235 237 / 0.06);
--color-tsl09-hover: color-mix(in oklab, oklch(0.93 0.005 235) 6%, transparent);
--color-tsl09-tint: rgb(92 196 221 / 0.17);
--color-tsl09-tint: color-mix(in oklab, oklch(0.72 0.13 210) 17%, transparent);
--font-tsl09-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-09 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}
```How this works
The grid removes the sharp edges of the fixed recipe. position:fixed escapes its container, breaks inside transformed ancestors, and needs its companion margin kept in sync by hand. grid-cols-[260px_1fr] h-svh plus per-pane overflow-y-auto gives the same visual result with none of that: the sidebar is effectively fixed because the shell itself never scrolls.
The finishing details are all utilities now. overscroll-contain stops a fast-scrolled sidebar from chain-scrolling the content behind it; the scrollbar properties are arbitrary but short; h-svh replaces the 100vh/100dvh pair with the unit that actually behaves on mobile.
Make it yours
- Fluid rail on ultrawide:
grid-cols-[clamp(220px,18vw,300px)_1fr]. - Add a fixed header:
grid-rows-[56px_1fr]with the sidebar spanning both rows viarow-span-2. - This shell is the base layer for demos 02, 06, 17 and 21 — they all assume exactly this structure.
Gotchas — read before shipping
- Ancestors must not constrain height, or
h-svhoverflows — mount the shell at body level or seth-fullup the chain. - Overflow belongs on the PANES. Putting it on the shell recreates the coupled-scroll problem the grid exists to solve.
- Check scrollbar-thumb contrast in light mode — a too-subtle thumb fails the visible-affordance heuristic on long lists.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 121+ | 18.2+ | 128+ | 121+ |
The versions gate scrollbar-color/scrollbar-width only, which are cosmetic; the grid shell works in any engine since 2017.