24 / 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 Multi-Level Nested Tree Sidebar with Details Branches
A file-explorer-grade tree: three levels of nested <details>, rotating chevrons, indent guides drawn as logical borders, and progressive padding from one --indent variable. Keyboard-operable out of the box because disclosure is native.
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-24 w-full h-svh min-h-svh grid grid-cols-[264px_1fr] font-tsl24-sans bg-tsl24-bg text-tsl24-ink">
<aside aria-label="Project files" class="bg-tsl24-panel border-r border-tsl24-line px-2.5 py-4 overflow-y-auto font-tsl24-mono [scrollbar-gutter:stable]">
<h2 class="px-3 pt-0.5 pb-3 text-[10.5px] font-semibold uppercase tracking-[0.12em] text-tsl24-mut">explorer</h2>
<details open class="group">
<summary class="flex items-center gap-[7px] min-h-9 px-2.5 ps-[calc(0.625rem+var(--indent,0)*1.125rem)] rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>src</summary>
<div class="[--indent:1] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<details open class="group/b2">
<summary class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b2:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>components</summary>
<div class="[--indent:2] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" aria-current="page" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover aria-[current=page]:text-tsl24-accent aria-[current=page]:bg-tsl24-tint focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>Sidebar.css</a>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>Sidebar.html</a>
</div>
</details>
<details class="group/b3">
<summary class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b3:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>tokens</summary>
<div class="[--indent:2] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>colors.css</a>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>spacing.css</a>
</div>
</details>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>index.html</a>
</div>
</details>
<details class="group/b4">
<summary class="flex items-center gap-[7px] min-h-9 px-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b4:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>docs</summary>
<div class="[--indent:1] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>README.md</a>
</div>
</details>
</aside>
<main class="p-8 overflow-y-auto [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Sidebar.css</h1>
<p class="max-w-[48ch] text-sm leading-relaxed text-tsl24-mut text-pretty">Every branch is a native <code class="font-tsl24-mono text-[12.5px]"><details></code> — keyboard toggling and state come free. Indent guides keep level 3 legible.</p>
</main>
</section><section class="tsl-24 w-full h-svh min-h-svh grid grid-cols-[264px_1fr] font-tsl24-sans bg-tsl24-bg text-tsl24-ink">
<aside aria-label="Project files" class="bg-tsl24-panel border-r border-tsl24-line px-2.5 py-4 overflow-y-auto font-tsl24-mono [scrollbar-gutter:stable]">
<h2 class="px-3 pt-0.5 pb-3 text-[10.5px] font-semibold uppercase tracking-[0.12em] text-tsl24-mut">explorer</h2>
<details open class="group">
<summary class="flex items-center gap-[7px] min-h-9 px-2.5 ps-[calc(0.625rem+var(--indent,0)*1.125rem)] rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>src</summary>
<div class="[--indent:1] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<details open class="group/b2">
<summary class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b2:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>components</summary>
<div class="[--indent:2] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" aria-current="page" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover aria-[current=page]:text-tsl24-accent aria-[current=page]:bg-tsl24-tint focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>Sidebar.css</a>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>Sidebar.html</a>
</div>
</details>
<details class="group/b3">
<summary class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b3:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>tokens</summary>
<div class="[--indent:2] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>colors.css</a>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>spacing.css</a>
</div>
</details>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>index.html</a>
</div>
</details>
<details class="group/b4">
<summary class="flex items-center gap-[7px] min-h-9 px-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b4:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>docs</summary>
<div class="[--indent:1] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>README.md</a>
</div>
</details>
</aside>
<main class="p-8 overflow-y-auto [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Sidebar.css</h1>
<p class="max-w-[48ch] text-sm leading-relaxed text-tsl24-mut text-pretty">Every branch is a native <code class="font-tsl24-mono text-[12.5px]"><details></code> — keyboard toggling and state come free. Indent guides keep level 3 legible.</p>
</main>
</section>@import "tailwindcss";
@theme {
--color-tsl24-bg: #101317;
--color-tsl24-bg: oklch(0.13 0.01 250);
--color-tsl24-panel: #171a1f;
--color-tsl24-panel: oklch(0.16 0.012 250);
--color-tsl24-ink: #e8e9ed;
--color-tsl24-ink: oklch(0.92 0.005 250);
--color-tsl24-mut: #8e9299;
--color-tsl24-mut: oklch(0.62 0.012 250);
--color-tsl24-line: #363a41;
--color-tsl24-line: oklch(0.27 0.014 250);
--color-tsl24-accent: #5cc6e3;
--color-tsl24-accent: oklch(0.75 0.12 210);
--color-tsl24-hover: rgb(232 233 237 / 0.06);
--color-tsl24-hover: color-mix(in oklab, oklch(0.92 0.005 250) 6%, transparent);
--color-tsl24-tint: rgb(92 198 227 / 0.12);
--color-tsl24-tint: color-mix(in oklab, oklch(0.75 0.12 210) 12%, transparent);
--font-tsl24-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tsl24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tsl-24 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}@import "tailwindcss";
@theme {
--color-tsl24-bg: #101317;
--color-tsl24-bg: oklch(0.13 0.01 250);
--color-tsl24-panel: #171a1f;
--color-tsl24-panel: oklch(0.16 0.012 250);
--color-tsl24-ink: #e8e9ed;
--color-tsl24-ink: oklch(0.92 0.005 250);
--color-tsl24-mut: #8e9299;
--color-tsl24-mut: oklch(0.62 0.012 250);
--color-tsl24-line: #363a41;
--color-tsl24-line: oklch(0.27 0.014 250);
--color-tsl24-accent: #5cc6e3;
--color-tsl24-accent: oklch(0.75 0.12 210);
--color-tsl24-hover: rgb(232 233 237 / 0.06);
--color-tsl24-hover: color-mix(in oklab, oklch(0.92 0.005 250) 6%, transparent);
--color-tsl24-tint: rgb(92 198 227 / 0.12);
--color-tsl24-tint: color-mix(in oklab, oklch(0.75 0.12 210) 12%, transparent);
--font-tsl24-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tsl24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tsl-24 {
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-tsl24-bg: #101317;
--color-tsl24-bg: oklch(0.13 0.01 250);
--color-tsl24-panel: #171a1f;
--color-tsl24-panel: oklch(0.16 0.012 250);
--color-tsl24-ink: #e8e9ed;
--color-tsl24-ink: oklch(0.92 0.005 250);
--color-tsl24-mut: #8e9299;
--color-tsl24-mut: oklch(0.62 0.012 250);
--color-tsl24-line: #363a41;
--color-tsl24-line: oklch(0.27 0.014 250);
--color-tsl24-accent: #5cc6e3;
--color-tsl24-accent: oklch(0.75 0.12 210);
--color-tsl24-hover: rgb(232 233 237 / 0.06);
--color-tsl24-hover: color-mix(in oklab, oklch(0.92 0.005 250) 6%, transparent);
--color-tsl24-tint: rgb(92 198 227 / 0.12);
--color-tsl24-tint: color-mix(in oklab, oklch(0.75 0.12 210) 12%, transparent);
--font-tsl24-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tsl24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tsl-24 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}@import "tailwindcss";
@theme {
--color-tsl24-bg: #101317;
--color-tsl24-bg: oklch(0.13 0.01 250);
--color-tsl24-panel: #171a1f;
--color-tsl24-panel: oklch(0.16 0.012 250);
--color-tsl24-ink: #e8e9ed;
--color-tsl24-ink: oklch(0.92 0.005 250);
--color-tsl24-mut: #8e9299;
--color-tsl24-mut: oklch(0.62 0.012 250);
--color-tsl24-line: #363a41;
--color-tsl24-line: oklch(0.27 0.014 250);
--color-tsl24-accent: #5cc6e3;
--color-tsl24-accent: oklch(0.75 0.12 210);
--color-tsl24-hover: rgb(232 233 237 / 0.06);
--color-tsl24-hover: color-mix(in oklab, oklch(0.92 0.005 250) 6%, transparent);
--color-tsl24-tint: rgb(92 198 227 / 0.12);
--color-tsl24-tint: color-mix(in oklab, oklch(0.75 0.12 210) 12%, transparent);
--font-tsl24-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tsl24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tsl-24 {
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.
- Named groups (
group/b2,group/b3) are mandatory in a nested tree: an unnamedgroup-open:inside a nested<details>matches the nearest ancestor group, which in a tree is usually the wrong branch. Name every level and the ambiguity disappears. - UI change from the CSS original: rows went from 34px to
min-h-9(36px, the documented floor for dense trees), and the rail keepsscrollbar-gutter:stableso expanding a branch does not shift the whole tree sideways.
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 Multi-Level Nested Tree Sidebar with Details Branches
Source: https://codefronts.com/layouts/tailwind-css-sidebar-layouts/tailwind-multi-level-nested-tree-sidebar-details/
A file-explorer-grade tree: three levels of nested <details>, rotating chevrons, indent guides drawn as logical borders, and progressive padding from one --indent variable. Keyboard-operable out of the box because disclosure is native.
## HTML
```html
<section class="tsl-24 w-full h-svh min-h-svh grid grid-cols-[264px_1fr] font-tsl24-sans bg-tsl24-bg text-tsl24-ink">
<aside aria-label="Project files" class="bg-tsl24-panel border-r border-tsl24-line px-2.5 py-4 overflow-y-auto font-tsl24-mono [scrollbar-gutter:stable]">
<h2 class="px-3 pt-0.5 pb-3 text-[10.5px] font-semibold uppercase tracking-[0.12em] text-tsl24-mut">explorer</h2>
<details open class="group">
<summary class="flex items-center gap-[7px] min-h-9 px-2.5 ps-[calc(0.625rem+var(--indent,0)*1.125rem)] rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>src</summary>
<div class="[--indent:1] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<details open class="group/b2">
<summary class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b2:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>components</summary>
<div class="[--indent:2] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" aria-current="page" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover aria-[current=page]:text-tsl24-accent aria-[current=page]:bg-tsl24-tint focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>Sidebar.css</a>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>Sidebar.html</a>
</div>
</details>
<details class="group/b3">
<summary class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b3:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>tokens</summary>
<div class="[--indent:2] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>colors.css</a>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>spacing.css</a>
</div>
</details>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>index.html</a>
</div>
</details>
<details class="group/b4">
<summary class="flex items-center gap-[7px] min-h-9 px-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b4:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>docs</summary>
<div class="[--indent:1] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>README.md</a>
</div>
</details>
</aside>
<main class="p-8 overflow-y-auto [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Sidebar.css</h1>
<p class="max-w-[48ch] text-sm leading-relaxed text-tsl24-mut text-pretty">Every branch is a native <code class="font-tsl24-mono text-[12.5px]"><details></code> — keyboard toggling and state come free. Indent guides keep level 3 legible.</p>
</main>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsl24-bg: #101317;
--color-tsl24-bg: oklch(0.13 0.01 250);
--color-tsl24-panel: #171a1f;
--color-tsl24-panel: oklch(0.16 0.012 250);
--color-tsl24-ink: #e8e9ed;
--color-tsl24-ink: oklch(0.92 0.005 250);
--color-tsl24-mut: #8e9299;
--color-tsl24-mut: oklch(0.62 0.012 250);
--color-tsl24-line: #363a41;
--color-tsl24-line: oklch(0.27 0.014 250);
--color-tsl24-accent: #5cc6e3;
--color-tsl24-accent: oklch(0.75 0.12 210);
--color-tsl24-hover: rgb(232 233 237 / 0.06);
--color-tsl24-hover: color-mix(in oklab, oklch(0.92 0.005 250) 6%, transparent);
--color-tsl24-tint: rgb(92 198 227 / 0.12);
--color-tsl24-tint: color-mix(in oklab, oklch(0.75 0.12 210) 12%, transparent);
--font-tsl24-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tsl24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tsl-24 {
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 Multi-Level Nested Tree Sidebar with Details Branches
Source: https://codefronts.com/layouts/tailwind-css-sidebar-layouts/tailwind-multi-level-nested-tree-sidebar-details/
A file-explorer-grade tree: three levels of nested <details>, rotating chevrons, indent guides drawn as logical borders, and progressive padding from one --indent variable. Keyboard-operable out of the box because disclosure is native.
## HTML
```html
<section class="tsl-24 w-full h-svh min-h-svh grid grid-cols-[264px_1fr] font-tsl24-sans bg-tsl24-bg text-tsl24-ink">
<aside aria-label="Project files" class="bg-tsl24-panel border-r border-tsl24-line px-2.5 py-4 overflow-y-auto font-tsl24-mono [scrollbar-gutter:stable]">
<h2 class="px-3 pt-0.5 pb-3 text-[10.5px] font-semibold uppercase tracking-[0.12em] text-tsl24-mut">explorer</h2>
<details open class="group">
<summary class="flex items-center gap-[7px] min-h-9 px-2.5 ps-[calc(0.625rem+var(--indent,0)*1.125rem)] rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>src</summary>
<div class="[--indent:1] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<details open class="group/b2">
<summary class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b2:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>components</summary>
<div class="[--indent:2] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" aria-current="page" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover aria-[current=page]:text-tsl24-accent aria-[current=page]:bg-tsl24-tint focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>Sidebar.css</a>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>Sidebar.html</a>
</div>
</details>
<details class="group/b3">
<summary class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b3:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>tokens</summary>
<div class="[--indent:2] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>colors.css</a>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>spacing.css</a>
</div>
</details>
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>index.html</a>
</div>
</details>
<details class="group/b4">
<summary class="flex items-center gap-[7px] min-h-9 px-2.5 rounded-lg text-[13px] font-medium text-tsl24-ink cursor-pointer list-none transition-colors duration-150 hover:bg-tsl24-hover [&::-webkit-details-marker]:hidden focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-tsl24-mut stroke-2 [stroke-linecap:round] [stroke-linejoin:round] transition-[rotate] duration-200 group-open/b4:rotate-90 motion-reduce:transition-none"><path d="m9 6 6 6-6 6"/></svg>docs</summary>
<div class="[--indent:1] flex flex-col border-s border-tsl24-line ms-[calc(1rem+(var(--indent)-1)*1.125rem)]">
<a href="#" class="flex items-center gap-[7px] min-h-9 ps-3 pe-2.5 rounded-lg text-[13px] text-tsl24-mut no-underline transition-colors duration-150 hover:text-tsl24-ink hover:bg-tsl24-hover focus-visible:outline-2 focus-visible:outline-tsl24-accent focus-visible:outline-offset-1"><svg viewBox="0 0 24 24" aria-hidden="true" class="w-3.5 h-3.5 fill-none stroke-current stroke-[1.7] [stroke-linejoin:round]"><path d="M6 2h9l5 5v15H6zM14 2v6h6"/></svg>README.md</a>
</div>
</details>
</aside>
<main class="p-8 overflow-y-auto [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Sidebar.css</h1>
<p class="max-w-[48ch] text-sm leading-relaxed text-tsl24-mut text-pretty">Every branch is a native <code class="font-tsl24-mono text-[12.5px]"><details></code> — keyboard toggling and state come free. Indent guides keep level 3 legible.</p>
</main>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsl24-bg: #101317;
--color-tsl24-bg: oklch(0.13 0.01 250);
--color-tsl24-panel: #171a1f;
--color-tsl24-panel: oklch(0.16 0.012 250);
--color-tsl24-ink: #e8e9ed;
--color-tsl24-ink: oklch(0.92 0.005 250);
--color-tsl24-mut: #8e9299;
--color-tsl24-mut: oklch(0.62 0.012 250);
--color-tsl24-line: #363a41;
--color-tsl24-line: oklch(0.27 0.014 250);
--color-tsl24-accent: #5cc6e3;
--color-tsl24-accent: oklch(0.75 0.12 210);
--color-tsl24-hover: rgb(232 233 237 / 0.06);
--color-tsl24-hover: color-mix(in oklab, oklch(0.92 0.005 250) 6%, transparent);
--color-tsl24-tint: rgb(92 198 227 / 0.12);
--color-tsl24-tint: color-mix(in oklab, oklch(0.75 0.12 210) 12%, transparent);
--font-tsl24-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tsl24-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tsl-24 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: dark;
}
```How this works
Native disclosure buys the hard parts: Enter/Space toggling, per-branch state with nothing to manage, and correct expanded/collapsed announcements at any depth. Tailwind contributes group-open:, which lets each branch's chevron declare its own rotation instead of relying on details[open] > summary svg.
Indent guides are what keep depth legible. Without the vertical hairline connecting children to their parent, level-3 rows visually float. The rail is on the container, inset to sit under the parent's chevron — per-row borders would break at every gap.
Make it yours
- Deeper nesting:
[--indent:4]— padding and guides are already parametric. - Exclusive sibling folders: same-level
nameattributes close siblings natively. - Expand/collapse all is the one thing CSS cannot do: three lines looping
details.open = true.
Gotchas — read before shipping
- Only the summary toggles — keep file links OUTSIDE summaries, or the link and the disclosure fight over the click.
- Guides belong on the container, never as per-row left borders.
- Deep trees plus small type get claustrophobic: 13px minimum, and let rows breathe at 36px even in dense mode.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
details/summary is one of the oldest interactive primitives; the name attribute (exclusive open) is 2024 sugar on top.