22 / 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 Section-Grouped Sidebar Navigation with Header Labels
How large admin tools stay navigable: links under quiet uppercase group labels, with no dividers anywhere. The whole technique is typographic — size, case, tracking, colour and a 10:1 spacing ratio — which makes it the demo where Tailwind's scale does the most work.
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-22 w-full h-svh min-h-svh grid grid-cols-[256px_1fr] font-tsl22-sans bg-tsl22-bg text-tsl22-ink">
<aside aria-label="Admin" class="bg-tsl22-panel border-r border-tsl22-line px-3.5 py-5 overflow-y-auto [scrollbar-gutter:stable]">
<div class="flex items-center gap-2.5 px-2.5 pt-0.5 pb-1.5 text-[15px] font-bold tracking-tight"><span aria-hidden="true" class="w-6 h-6 rounded-[7px] bg-[conic-gradient(from_80deg,var(--color-tsl22-accent),oklch(0.62_0.13_190))]"></span>Control Plane</div>
<section aria-labelledby="tsl22-g1" class="mt-[22px]">
<h2 id="tsl22-g1" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Provisioning</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" aria-current="page" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover aria-[current=page]:text-tsl22-accent aria-[current=page]:bg-tsl22-tint aria-[current=page]:font-semibold focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Clusters <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">8</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Node pools</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Volumes <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">42</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Snapshots</a></li>
</ul>
</section>
<section aria-labelledby="tsl22-g2" class="mt-[22px]">
<h2 id="tsl22-g2" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Networking</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Load balancers</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Firewalls <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">3</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">DNS zones</a></li>
</ul>
</section>
<section aria-labelledby="tsl22-g3" class="mt-[22px]">
<h2 id="tsl22-g3" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Access</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Team members</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">API tokens</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Audit log</a></li>
</ul>
</section>
</aside>
<main class="p-8 overflow-y-auto [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Clusters</h1>
<p class="max-w-[48ch] text-sm leading-relaxed text-tsl22-mut text-pretty">No divider lines anywhere — the 22px-to-2px spacing rhythm and the label typography do all the grouping.</p>
</main>
</section><section class="tsl-22 w-full h-svh min-h-svh grid grid-cols-[256px_1fr] font-tsl22-sans bg-tsl22-bg text-tsl22-ink">
<aside aria-label="Admin" class="bg-tsl22-panel border-r border-tsl22-line px-3.5 py-5 overflow-y-auto [scrollbar-gutter:stable]">
<div class="flex items-center gap-2.5 px-2.5 pt-0.5 pb-1.5 text-[15px] font-bold tracking-tight"><span aria-hidden="true" class="w-6 h-6 rounded-[7px] bg-[conic-gradient(from_80deg,var(--color-tsl22-accent),oklch(0.62_0.13_190))]"></span>Control Plane</div>
<section aria-labelledby="tsl22-g1" class="mt-[22px]">
<h2 id="tsl22-g1" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Provisioning</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" aria-current="page" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover aria-[current=page]:text-tsl22-accent aria-[current=page]:bg-tsl22-tint aria-[current=page]:font-semibold focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Clusters <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">8</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Node pools</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Volumes <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">42</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Snapshots</a></li>
</ul>
</section>
<section aria-labelledby="tsl22-g2" class="mt-[22px]">
<h2 id="tsl22-g2" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Networking</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Load balancers</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Firewalls <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">3</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">DNS zones</a></li>
</ul>
</section>
<section aria-labelledby="tsl22-g3" class="mt-[22px]">
<h2 id="tsl22-g3" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Access</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Team members</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">API tokens</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Audit log</a></li>
</ul>
</section>
</aside>
<main class="p-8 overflow-y-auto [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Clusters</h1>
<p class="max-w-[48ch] text-sm leading-relaxed text-tsl22-mut text-pretty">No divider lines anywhere — the 22px-to-2px spacing rhythm and the label typography do all the grouping.</p>
</main>
</section>@import "tailwindcss";
@theme {
--color-tsl22-bg: #fcfdfe;
--color-tsl22-bg: oklch(0.99 0.002 230);
--color-tsl22-panel: #f2f4f6;
--color-tsl22-panel: oklch(0.965 0.005 230);
--color-tsl22-ink: #383e47;
--color-tsl22-ink: oklch(0.26 0.02 230);
--color-tsl22-mut: #6f7680;
--color-tsl22-mut: oklch(0.5 0.015 230);
--color-tsl22-label: #7e848d;
--color-tsl22-label: oklch(0.55 0.014 230);
--color-tsl22-line: #dee1e5;
--color-tsl22-line: oklch(0.89 0.008 230);
--color-tsl22-accent: #2f62c4;
--color-tsl22-accent: oklch(0.5 0.15 235);
--color-tsl22-chip: rgb(56 62 71 / 0.07);
--color-tsl22-chip: color-mix(in oklab, oklch(0.26 0.02 230) 7%, transparent);
--color-tsl22-hover: rgb(56 62 71 / 0.05);
--color-tsl22-hover: color-mix(in oklab, oklch(0.26 0.02 230) 5%, transparent);
--color-tsl22-tint: rgb(47 98 196 / 0.1);
--color-tsl22-tint: color-mix(in oklab, oklch(0.5 0.15 235) 10%, transparent);
--font-tsl22-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-22 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: light;
}@import "tailwindcss";
@theme {
--color-tsl22-bg: #fcfdfe;
--color-tsl22-bg: oklch(0.99 0.002 230);
--color-tsl22-panel: #f2f4f6;
--color-tsl22-panel: oklch(0.965 0.005 230);
--color-tsl22-ink: #383e47;
--color-tsl22-ink: oklch(0.26 0.02 230);
--color-tsl22-mut: #6f7680;
--color-tsl22-mut: oklch(0.5 0.015 230);
--color-tsl22-label: #7e848d;
--color-tsl22-label: oklch(0.55 0.014 230);
--color-tsl22-line: #dee1e5;
--color-tsl22-line: oklch(0.89 0.008 230);
--color-tsl22-accent: #2f62c4;
--color-tsl22-accent: oklch(0.5 0.15 235);
--color-tsl22-chip: rgb(56 62 71 / 0.07);
--color-tsl22-chip: color-mix(in oklab, oklch(0.26 0.02 230) 7%, transparent);
--color-tsl22-hover: rgb(56 62 71 / 0.05);
--color-tsl22-hover: color-mix(in oklab, oklch(0.26 0.02 230) 5%, transparent);
--color-tsl22-tint: rgb(47 98 196 / 0.1);
--color-tsl22-tint: color-mix(in oklab, oklch(0.5 0.15 235) 10%, transparent);
--font-tsl22-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-22 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: light;
}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-tsl22-bg: #fcfdfe;
--color-tsl22-bg: oklch(0.99 0.002 230);
--color-tsl22-panel: #f2f4f6;
--color-tsl22-panel: oklch(0.965 0.005 230);
--color-tsl22-ink: #383e47;
--color-tsl22-ink: oklch(0.26 0.02 230);
--color-tsl22-mut: #6f7680;
--color-tsl22-mut: oklch(0.5 0.015 230);
--color-tsl22-label: #7e848d;
--color-tsl22-label: oklch(0.55 0.014 230);
--color-tsl22-line: #dee1e5;
--color-tsl22-line: oklch(0.89 0.008 230);
--color-tsl22-accent: #2f62c4;
--color-tsl22-accent: oklch(0.5 0.15 235);
--color-tsl22-chip: rgb(56 62 71 / 0.07);
--color-tsl22-chip: color-mix(in oklab, oklch(0.26 0.02 230) 7%, transparent);
--color-tsl22-hover: rgb(56 62 71 / 0.05);
--color-tsl22-hover: color-mix(in oklab, oklch(0.26 0.02 230) 5%, transparent);
--color-tsl22-tint: rgb(47 98 196 / 0.1);
--color-tsl22-tint: color-mix(in oklab, oklch(0.5 0.15 235) 10%, transparent);
--font-tsl22-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-22 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: light;
}@import "tailwindcss";
@theme {
--color-tsl22-bg: #fcfdfe;
--color-tsl22-bg: oklch(0.99 0.002 230);
--color-tsl22-panel: #f2f4f6;
--color-tsl22-panel: oklch(0.965 0.005 230);
--color-tsl22-ink: #383e47;
--color-tsl22-ink: oklch(0.26 0.02 230);
--color-tsl22-mut: #6f7680;
--color-tsl22-mut: oklch(0.5 0.015 230);
--color-tsl22-label: #7e848d;
--color-tsl22-label: oklch(0.55 0.014 230);
--color-tsl22-line: #dee1e5;
--color-tsl22-line: oklch(0.89 0.008 230);
--color-tsl22-accent: #2f62c4;
--color-tsl22-accent: oklch(0.5 0.15 235);
--color-tsl22-chip: rgb(56 62 71 / 0.07);
--color-tsl22-chip: color-mix(in oklab, oklch(0.26 0.02 230) 7%, transparent);
--color-tsl22-hover: rgb(56 62 71 / 0.05);
--color-tsl22-hover: color-mix(in oklab, oklch(0.26 0.02 230) 5%, transparent);
--color-tsl22-tint: rgb(47 98 196 / 0.1);
--color-tsl22-tint: color-mix(in oklab, oklch(0.5 0.15 235) 10%, transparent);
--font-tsl22-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-22 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: light;
}<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.
- A demo made entirely of type is the fairest test of a utility framework, and this one passes: every decision — 10.5px, semibold, uppercase, 0.09em, the label colour — is visible on the element rather than distributed across a stylesheet.
- UI change from the CSS original: rows are
min-h-11, and the group label uses a solid token at 4.6:1 instead ofcolor-mix(…85%,transparent)— alpha-muted labels on a tinted panel were the one contrast failure in the original.
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 Section-Grouped Sidebar Navigation with Header Labels
Source: https://codefronts.com/layouts/tailwind-css-sidebar-layouts/tailwind-section-grouped-sidebar-navigation-labels/
How large admin tools stay navigable: links under quiet uppercase group labels, with no dividers anywhere. The whole technique is typographic — size, case, tracking, colour and a 10:1 spacing ratio — which makes it the demo where Tailwind's scale does the most work.
## HTML
```html
<section class="tsl-22 w-full h-svh min-h-svh grid grid-cols-[256px_1fr] font-tsl22-sans bg-tsl22-bg text-tsl22-ink">
<aside aria-label="Admin" class="bg-tsl22-panel border-r border-tsl22-line px-3.5 py-5 overflow-y-auto [scrollbar-gutter:stable]">
<div class="flex items-center gap-2.5 px-2.5 pt-0.5 pb-1.5 text-[15px] font-bold tracking-tight"><span aria-hidden="true" class="w-6 h-6 rounded-[7px] bg-[conic-gradient(from_80deg,var(--color-tsl22-accent),oklch(0.62_0.13_190))]"></span>Control Plane</div>
<section aria-labelledby="tsl22-g1" class="mt-[22px]">
<h2 id="tsl22-g1" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Provisioning</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" aria-current="page" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover aria-[current=page]:text-tsl22-accent aria-[current=page]:bg-tsl22-tint aria-[current=page]:font-semibold focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Clusters <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">8</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Node pools</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Volumes <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">42</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Snapshots</a></li>
</ul>
</section>
<section aria-labelledby="tsl22-g2" class="mt-[22px]">
<h2 id="tsl22-g2" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Networking</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Load balancers</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Firewalls <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">3</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">DNS zones</a></li>
</ul>
</section>
<section aria-labelledby="tsl22-g3" class="mt-[22px]">
<h2 id="tsl22-g3" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Access</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Team members</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">API tokens</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Audit log</a></li>
</ul>
</section>
</aside>
<main class="p-8 overflow-y-auto [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Clusters</h1>
<p class="max-w-[48ch] text-sm leading-relaxed text-tsl22-mut text-pretty">No divider lines anywhere — the 22px-to-2px spacing rhythm and the label typography do all the grouping.</p>
</main>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsl22-bg: #fcfdfe;
--color-tsl22-bg: oklch(0.99 0.002 230);
--color-tsl22-panel: #f2f4f6;
--color-tsl22-panel: oklch(0.965 0.005 230);
--color-tsl22-ink: #383e47;
--color-tsl22-ink: oklch(0.26 0.02 230);
--color-tsl22-mut: #6f7680;
--color-tsl22-mut: oklch(0.5 0.015 230);
--color-tsl22-label: #7e848d;
--color-tsl22-label: oklch(0.55 0.014 230);
--color-tsl22-line: #dee1e5;
--color-tsl22-line: oklch(0.89 0.008 230);
--color-tsl22-accent: #2f62c4;
--color-tsl22-accent: oklch(0.5 0.15 235);
--color-tsl22-chip: rgb(56 62 71 / 0.07);
--color-tsl22-chip: color-mix(in oklab, oklch(0.26 0.02 230) 7%, transparent);
--color-tsl22-hover: rgb(56 62 71 / 0.05);
--color-tsl22-hover: color-mix(in oklab, oklch(0.26 0.02 230) 5%, transparent);
--color-tsl22-tint: rgb(47 98 196 / 0.1);
--color-tsl22-tint: color-mix(in oklab, oklch(0.5 0.15 235) 10%, transparent);
--font-tsl22-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-22 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: light;
}
```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 Section-Grouped Sidebar Navigation with Header Labels
Source: https://codefronts.com/layouts/tailwind-css-sidebar-layouts/tailwind-section-grouped-sidebar-navigation-labels/
How large admin tools stay navigable: links under quiet uppercase group labels, with no dividers anywhere. The whole technique is typographic — size, case, tracking, colour and a 10:1 spacing ratio — which makes it the demo where Tailwind's scale does the most work.
## HTML
```html
<section class="tsl-22 w-full h-svh min-h-svh grid grid-cols-[256px_1fr] font-tsl22-sans bg-tsl22-bg text-tsl22-ink">
<aside aria-label="Admin" class="bg-tsl22-panel border-r border-tsl22-line px-3.5 py-5 overflow-y-auto [scrollbar-gutter:stable]">
<div class="flex items-center gap-2.5 px-2.5 pt-0.5 pb-1.5 text-[15px] font-bold tracking-tight"><span aria-hidden="true" class="w-6 h-6 rounded-[7px] bg-[conic-gradient(from_80deg,var(--color-tsl22-accent),oklch(0.62_0.13_190))]"></span>Control Plane</div>
<section aria-labelledby="tsl22-g1" class="mt-[22px]">
<h2 id="tsl22-g1" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Provisioning</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" aria-current="page" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover aria-[current=page]:text-tsl22-accent aria-[current=page]:bg-tsl22-tint aria-[current=page]:font-semibold focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Clusters <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">8</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Node pools</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Volumes <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">42</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Snapshots</a></li>
</ul>
</section>
<section aria-labelledby="tsl22-g2" class="mt-[22px]">
<h2 id="tsl22-g2" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Networking</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Load balancers</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Firewalls <span class="ms-auto rounded-full px-2 py-[3px] text-[11px] font-semibold text-tsl22-mut bg-tsl22-chip">3</span></a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">DNS zones</a></li>
</ul>
</section>
<section aria-labelledby="tsl22-g3" class="mt-[22px]">
<h2 id="tsl22-g3" class="px-3 pb-[7px] text-[10.5px] font-semibold uppercase tracking-[0.09em] text-tsl22-label">Access</h2>
<ul class="list-none m-0 p-0 flex flex-col gap-0.5">
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Team members</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">API tokens</a></li>
<li><a href="#" class="flex items-center min-h-11 px-3 rounded-[9px] text-sm font-medium text-tsl22-mut no-underline transition-colors duration-150 hover:text-tsl22-ink hover:bg-tsl22-hover focus-visible:outline-2 focus-visible:outline-tsl22-accent focus-visible:outline-offset-1">Audit log</a></li>
</ul>
</section>
</aside>
<main class="p-8 overflow-y-auto [scrollbar-gutter:stable]">
<h1 class="text-[22px] font-semibold leading-tight mb-2.5">Clusters</h1>
<p class="max-w-[48ch] text-sm leading-relaxed text-tsl22-mut text-pretty">No divider lines anywhere — the 22px-to-2px spacing rhythm and the label typography do all the grouping.</p>
</main>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tsl22-bg: #fcfdfe;
--color-tsl22-bg: oklch(0.99 0.002 230);
--color-tsl22-panel: #f2f4f6;
--color-tsl22-panel: oklch(0.965 0.005 230);
--color-tsl22-ink: #383e47;
--color-tsl22-ink: oklch(0.26 0.02 230);
--color-tsl22-mut: #6f7680;
--color-tsl22-mut: oklch(0.5 0.015 230);
--color-tsl22-label: #7e848d;
--color-tsl22-label: oklch(0.55 0.014 230);
--color-tsl22-line: #dee1e5;
--color-tsl22-line: oklch(0.89 0.008 230);
--color-tsl22-accent: #2f62c4;
--color-tsl22-accent: oklch(0.5 0.15 235);
--color-tsl22-chip: rgb(56 62 71 / 0.07);
--color-tsl22-chip: color-mix(in oklab, oklch(0.26 0.02 230) 7%, transparent);
--color-tsl22-hover: rgb(56 62 71 / 0.05);
--color-tsl22-hover: color-mix(in oklab, oklch(0.26 0.02 230) 5%, transparent);
--color-tsl22-tint: rgb(47 98 196 / 0.1);
--color-tsl22-tint: color-mix(in oklab, oklch(0.5 0.15 235) 10%, transparent);
--font-tsl22-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tsl-22 {
width: 100%;
height: 100svh;
min-height: 100svh;
color-scheme: light;
}
```How this works
Double contrast does the chunking. Labels differ from links on four axes at once — size, weight, case and colour — which is what lets the eye read 25 links as three groups without a single divider line. Get the spacing ratio wrong (3:1 rather than 10:1) and the grouping collapses no matter how the labels look.
Semantics mirror the type. Each group is a section with a real heading, so a screen reader announces 'Provisioning, list, 4 items' — the same wayfinding the typography gives sighted users.
Make it yours
- Keep the group-gap to link-gap ratio at 8:1 or better; it is the one number to extract as a token.
- Collapsible groups: wrap each list in demo 15's
<details>with the label as the summary. - Past 25 links, add demo 21's sticky search above the first group — the two compose directly.
Gotchas — read before shipping
- Labels must not be links or buttons. A navigable heading confuses both muscle memory and the screen-reader link list.
- Do not skip heading levels inside groups; jumped levels break rotor navigation.
- Uppercase with tight tracking under 10px is unreadable for dyslexic users —
text-[10.5px] tracking-[0.09em]is the floor, not a suggestion.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Pure typography and flex; nothing gated beyond Tailwind v4's own floor.