sidebar navigation collapsible groups nested accordion details-summary sidebar collapsible accordion groups nested nav expand collapse details summary sidebar with expandable navigation groups collapsible nested menu sections
Sidebar Collapsible
Fetch pattern JSON:
curl https://webspire.de/patterns/sidebar/collapsible.json collapsible.html
<aside class="ws-sidebar flex h-screen w-16 flex-col border-r border-[var(--ws-sidebar-border)] bg-[var(--ws-sidebar-bg)] transition-all duration-200 lg:w-64">
<!-- Brand -->
<div class="flex h-16 items-center border-b border-[var(--ws-sidebar-border)] px-4 lg:px-6">
<svg class="h-8 w-8 flex-shrink-0 text-[var(--ws-sidebar-active-text)]" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6.429 9.75L2.25 12l4.179 2.25m0-4.5l5.571 3 5.571-3m-11.142 0L2.25 7.5 12 2.25l9.75 5.25-4.179 2.25m0 0L12 12.75 6.429 9.75m11.142 0l4.179 2.25L12 17.25 2.25 12l4.179-2.25m11.142 0l4.179 2.25L12 22.5l-9.75-5.25 4.179-2.25" />
</svg>
<span class="ml-3 hidden text-lg font-bold text-[var(--ws-sidebar-text)] lg:block">Webspire</span>
</div>
<!-- Collapsible Navigation Groups -->
<nav aria-label="Sidebar navigation" class="flex-1 space-y-1 overflow-y-auto px-2 py-4 lg:px-3">
<!-- Group: Dashboard (open by default) -->
<details open class="group">
<summary class="flex cursor-pointer list-none items-center gap-3 rounded-lg px-3 py-2.5 text-[var(--ws-sidebar-text)] transition hover:bg-[var(--ws-sidebar-hover-bg)] [&::-webkit-details-marker]:hidden">
<svg class="h-5 w-5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
</svg>
<span class="hidden flex-1 text-sm font-semibold lg:block">Dashboard</span>
<svg class="hidden h-4 w-4 text-[var(--ws-sidebar-text-muted)] transition-transform group-open:rotate-90 lg:block" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</summary>
<ul class="mt-1 hidden space-y-0.5 pl-11 lg:block">
<li>
<a href="#" class="block rounded-md bg-[var(--ws-sidebar-active-bg)] px-3 py-2 text-sm font-medium text-[var(--ws-sidebar-active-text)]" aria-current="page">Overview</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Analytics</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Reports</a>
</li>
</ul>
</details>
<!-- Group: Content -->
<details class="group">
<summary class="flex cursor-pointer list-none items-center gap-3 rounded-lg px-3 py-2.5 text-[var(--ws-sidebar-text)] transition hover:bg-[var(--ws-sidebar-hover-bg)] [&::-webkit-details-marker]:hidden">
<svg class="h-5 w-5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
</svg>
<span class="hidden flex-1 text-sm font-semibold lg:block">Content</span>
<svg class="hidden h-4 w-4 text-[var(--ws-sidebar-text-muted)] transition-transform group-open:rotate-90 lg:block" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</summary>
<ul class="mt-1 hidden space-y-0.5 pl-11 lg:block">
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Pages</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Blog Posts</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Media Library</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Categories</a>
</li>
</ul>
</details>
<!-- Group: Users -->
<details class="group">
<summary class="flex cursor-pointer list-none items-center gap-3 rounded-lg px-3 py-2.5 text-[var(--ws-sidebar-text)] transition hover:bg-[var(--ws-sidebar-hover-bg)] [&::-webkit-details-marker]:hidden">
<svg class="h-5 w-5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" />
</svg>
<span class="hidden flex-1 text-sm font-semibold lg:block">Users</span>
<svg class="hidden h-4 w-4 text-[var(--ws-sidebar-text-muted)] transition-transform group-open:rotate-90 lg:block" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</summary>
<ul class="mt-1 hidden space-y-0.5 pl-11 lg:block">
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">All Users</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Roles</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Permissions</a>
</li>
</ul>
</details>
<!-- Separator -->
<div class="my-3 border-t border-[var(--ws-sidebar-border)]"></div>
<!-- Group: Settings -->
<details class="group">
<summary class="flex cursor-pointer list-none items-center gap-3 rounded-lg px-3 py-2.5 text-[var(--ws-sidebar-text)] transition hover:bg-[var(--ws-sidebar-hover-bg)] [&::-webkit-details-marker]:hidden">
<svg class="h-5 w-5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span class="hidden flex-1 text-sm font-semibold lg:block">Settings</span>
<svg class="hidden h-4 w-4 text-[var(--ws-sidebar-text-muted)] transition-transform group-open:rotate-90 lg:block" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</summary>
<ul class="mt-1 hidden space-y-0.5 pl-11 lg:block">
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">General</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Integrations</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">Billing</a>
</li>
<li>
<a href="#" class="block rounded-md px-3 py-2 text-sm text-[var(--ws-sidebar-text-muted)] transition hover:bg-[var(--ws-sidebar-hover-bg)] hover:text-[var(--ws-sidebar-text)]">API Keys</a>
</li>
</ul>
</details>
</nav>
<!-- User profile -->
<div class="border-t border-[var(--ws-sidebar-border)] px-2 py-4 lg:px-4">
<div class="flex items-center gap-3 rounded-lg px-2 py-2 transition hover:bg-[var(--ws-sidebar-hover-bg)]">
<div class="h-8 w-8 flex-shrink-0 rounded-full bg-[var(--ws-sidebar-hover-bg)] flex items-center justify-center">
<svg class="h-5 w-5 text-[var(--ws-sidebar-text-muted)]" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" /></svg>
</div>
<div class="hidden min-w-0 lg:block">
<p class="truncate text-sm font-medium text-[var(--ws-sidebar-text)]">Alex Rivera</p>
<p class="truncate text-xs text-[var(--ws-sidebar-text-muted)]">alex@company.com</p>
</div>
<svg class="ml-auto hidden h-4 w-4 text-[var(--ws-sidebar-text-muted)] lg:block" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.625 12a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
</div>
</aside>
Details
Responsive Dark Mode Tailwind Only SSR Safe Copy & Paste
Stable Published
sidebarnavigationcollapsiblegroupsnestedaccordiondetails-summary
Slots
| Name | Required | Description |
|---|---|---|
| brand | Yes | Logo or brand area at the top of the sidebar. |
| groups | Yes | Collapsible navigation groups with nested links. |
| user | No | User profile section at the bottom. |
Props
| Name | Type | Default | Description |
|---|---|---|---|
| collapsed | boolean | false | Whether the sidebar shows icon-only mode. |
Enhanced sidebar with collapsible navigation groups. Extends sidebar/base with grouped sections using native <details>/<summary> elements for zero-JS expand/collapse. Each group has an icon header and nested sub-items with active state support. Fully responsive: collapses to icon-only below lg breakpoint.