30 Tailwind CSS Sidebar Layouts
24 / 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 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.

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-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 [&amp;::-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 [&amp;::-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 [&amp;::-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 [&amp;::-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]">&lt;details&gt;</code> &mdash; 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;
}

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-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;
}
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.

  • Named groups (group/b2, group/b3) are mandatory in a nested tree: an unnamed group-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 keeps scrollbar-gutter:stable so expanding a branch does not shift the whole tree sideways.
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 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 [&amp;::-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 [&amp;::-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 [&amp;::-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 [&amp;::-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]">&lt;details&gt;</code> &mdash; 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 name attributes 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

ChromeSafariFirefoxEdge
111+16.4+128+111+

details/summary is one of the oldest interactive primitives; the name attribute (exclusive open) is 2024 sugar on top.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Theme tokensset in @theme, used by a utility

Search CodeFronts

Loading…