Dashboard Layout

App-style layout with sidebar, topbar, and scrollable main area.

Header + Sidebar + Content

Sidebar and topbar stay put; only the content column scrolls. Scroll the content area below — the sidebar and topbar won't move.

Acme Admin user@acme.com

Page content

This column scrolls independently. Everything below exists only to make that scrollbar appear.

Paragraph 1 — filler content so the main area overflows and scrolls on its own.

Paragraph 2 — filler content so the main area overflows and scrolls on its own.

Paragraph 3 — filler content so the main area overflows and scrolls on its own.

Paragraph 4 — filler content so the main area overflows and scrolls on its own.

Paragraph 5 — filler content so the main area overflows and scrolls on its own.

Paragraph 6 — filler content so the main area overflows and scrolls on its own.

Paragraph 7 — filler content so the main area overflows and scrolls on its own.

Paragraph 8 — filler content so the main area overflows and scrolls on its own.

<div class="h-screen flex flex-col">
  <header class="h-14 flex items-center px-4">...</header>
  <div class="flex flex-1 min-h-0">
    <nav class="w-56 flex-shrink-0 overflow-y-auto">...</nav>
    <main class="flex-1 overflow-y-auto p-6">...</main>
  </div>
</div>

Collapsible Nav Rail

Toggle button shrinks the sidebar to an icon rail, hiding labels instead of the whole nav.

Acme Admin

Content area stays the same regardless of sidebar state.

<div x-data="{ collapsed: false }">
  <button @click="collapsed = !collapsed">Toggle</button>
  <nav :class="collapsed ? 'w-14' : 'w-56'" class="transition-all duration-200">
    <a href="#">
      <span>Icon</span>
      <span x-show="!collapsed" x-cloak>Label</span>
    </a>
  </nav>
</div>

Top Nav + Content

No sidebar — navigation lives in the topbar instead, freeing the full width for content below.

Acme Admin Overview Orders Settings

Full-width content with no sidebar gutter to account for.

<div class="h-screen flex flex-col">
  <header class="h-14 flex items-center px-4 gap-5">
    <a href="#">Overview</a>
    <a href="#">Orders</a>
  </header>
  <main class="flex-1 overflow-y-auto p-6">...</main>
</div>

Multi-Panel

Three independently-scrolling regions: nav, primary content, and a secondary detail panel.

Acme Admin

Primary list content.

<div class="flex flex-1 min-h-0">
  <nav class="w-40 flex-shrink-0 overflow-y-auto">...</nav>
  <main class="flex-1 overflow-y-auto p-5">...</main>
  <aside class="w-64 flex-shrink-0 overflow-y-auto p-5">...</aside>
</div>

Resizable Split

Drag the handle between the two panels to resize. Width is clamped between 140px and 360px.

Left panel

Current width: px

Right panel fills the remaining space.

<div x-data="{ width: 224, dragging: false, /* ...drag handlers */ }"
     @mousemove.window="onDrag($event)" @mouseup.window="stopDrag()">
  <div :style="`width: ${width}px`">Left panel</div>
  <div @mousedown="startDrag()" class="cursor-col-resize"></div>
  <main class="flex-1">Right panel</main>
</div>

Edge Cases

An empty nav list shouldn't collapse the sidebar to nothing, and a narrow viewport should move the sidebar off-canvas rather than squeeze it.

Empty nav — sidebar keeps its width and an empty-state hint

Content area is unaffected by an empty nav.

Narrow viewport — sidebar goes off-canvas behind a toggle

Acme

Mobile content, full width by default.