Dashboard Layout Patterns
Dashboard layout patterns with sidebar nav, header, content area, and responsive breakpoints
You are a UI architect who designs dashboard layouts that scale from mobile to ultrawide screens. You build layouts that feel native on every device, with sidebars that collapse gracefully, headers that stay useful, and content areas that maximize data density without overwhelming users. ## Key Points - Set `h-screen overflow-hidden` on the root to prevent double scrollbars; only `main` should scroll. - Use `flex-col` and `flex-1` for the content column so the header stays fixed without `position: sticky` hacks. - Store sidebar collapsed state in localStorage so it persists across page loads. - Use `transition-all duration-200` on sidebar width for smooth collapse animation. - Add `print:hidden` to sidebar and header so printed dashboards show only content. - Keep sidebar nav items to 7 or fewer top-level groups; use collapsible sections for more. - **Fixed pixel widths everywhere**: Using `w-[247px]` instead of design tokens like `w-64` makes layouts brittle. Stick to Tailwind's spacing scale. - **Hiding mobile nav entirely**: Removing navigation on mobile forces users to guess how to navigate. Always provide a hamburger menu or bottom nav. - **Nesting scrollable containers**: A scrollable sidebar inside a scrollable page inside a scrollable modal creates scroll-trapping. Limit scroll to one axis per container. - **Header taller than 64px**: Tall headers eat into content area. Keep headers slim; move secondary actions to dropdowns. - **No loading skeleton for the shell**: Showing a blank screen while the sidebar loads causes layout shift. Render the shell immediately with skeleton content.
skilldb get ux-design-patterns-skills/dashboard-layoutFull skill: 156 linesDashboard Layout Patterns
You are a UI architect who designs dashboard layouts that scale from mobile to ultrawide screens. You build layouts that feel native on every device, with sidebars that collapse gracefully, headers that stay useful, and content areas that maximize data density without overwhelming users.
Core Philosophy
Structure Before Style
Every dashboard has three zones: navigation (sidebar), context (header), and workspace (content). Get the skeleton right before adding polish. A well-structured layout survives redesigns.
Progressive Disclosure on Small Screens
Mobile dashboards are not shrunken desktops. Collapse the sidebar to icons, stack content vertically, and hide secondary actions behind menus. Every pixel must earn its place.
Consistent Landmark Regions
Use semantic HTML and ARIA landmarks so screen readers and keyboard users can jump between sections. The sidebar is nav, the header is header, the content is main.
Techniques
1. Base Dashboard Shell
<div className="flex h-screen overflow-hidden bg-gray-50 dark:bg-gray-900">
<aside className="hidden md:flex md:w-64 md:flex-col border-r border-gray-200 dark:border-gray-800">
<Sidebar />
</aside>
<div className="flex flex-1 flex-col overflow-hidden">
<header className="h-16 border-b border-gray-200 dark:border-gray-800 flex items-center px-4">
<Header />
</header>
<main className="flex-1 overflow-y-auto p-6">
{children}
</main>
</div>
</div>
2. Collapsible Sidebar with State
const [collapsed, setCollapsed] = useState(false);
<aside className={cn(
"hidden md:flex md:flex-col border-r transition-all duration-200",
collapsed ? "md:w-16" : "md:w-64"
)}>
<button onClick={() => setCollapsed(!collapsed)} className="p-2 hover:bg-gray-100 rounded">
{collapsed ? <ChevronRight /> : <ChevronLeft />}
</button>
<NavItems collapsed={collapsed} />
</aside>
3. Sidebar Nav Item with Tooltip on Collapse
function NavItem({ icon: Icon, label, href, collapsed }: NavItemProps) {
const item = (
<a href={href} className="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-sm font-medium text-gray-700 dark:text-gray-300">
<Icon className="h-5 w-5 shrink-0" />
{!collapsed && <span>{label}</span>}
</a>
);
return collapsed ? <Tooltip content={label}>{item}</Tooltip> : item;
}
4. Mobile Sidebar as Overlay Drawer
<Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
<SheetContent side="left" className="w-72 p-0">
<Sidebar onNavigate={() => setMobileOpen(false)} />
</SheetContent>
</Sheet>
<button className="md:hidden p-2" onClick={() => setMobileOpen(true)}>
<Menu className="h-5 w-5" />
</button>
5. Header with Breadcrumb and Actions
<header className="h-16 border-b flex items-center justify-between px-4 lg:px-6">
<div className="flex items-center gap-2 text-sm text-gray-500">
<a href="/dashboard">Dashboard</a>
<ChevronRight className="h-3 w-3" />
<span className="text-gray-900 dark:text-white font-medium">Analytics</span>
</div>
<div className="flex items-center gap-2">
<NotificationBell />
<UserMenu />
</div>
</header>
6. Content Grid for Stat Cards
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
{stats.map(stat => (
<div key={stat.label} className="bg-white dark:bg-gray-800 rounded-xl border p-4">
<p className="text-sm text-gray-500">{stat.label}</p>
<p className="text-2xl font-semibold mt-1">{stat.value}</p>
<p className={cn("text-xs mt-1", stat.change > 0 ? "text-green-600" : "text-red-600")}>
{stat.change > 0 ? "+" : ""}{stat.change}%
</p>
</div>
))}
</div>
7. Responsive Two-Column Content
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="lg:col-span-2">
<ChartPanel />
</div>
<div>
<RecentActivity />
</div>
</div>
8. Sticky Sub-Navigation Tabs
<div className="sticky top-0 z-10 bg-white dark:bg-gray-900 border-b">
<nav className="flex gap-1 px-4 overflow-x-auto">
{tabs.map(tab => (
<button key={tab.id} className={cn(
"px-3 py-2 text-sm font-medium whitespace-nowrap border-b-2 transition-colors",
active === tab.id
? "border-blue-600 text-blue-600"
: "border-transparent text-gray-500 hover:text-gray-900"
)}>
{tab.label}
</button>
))}
</nav>
</div>
Best Practices
- Set
h-screen overflow-hiddenon the root to prevent double scrollbars; onlymainshould scroll. - Use
flex-colandflex-1for the content column so the header stays fixed withoutposition: stickyhacks. - Store sidebar collapsed state in localStorage so it persists across page loads.
- Use
transition-all duration-200on sidebar width for smooth collapse animation. - Add
print:hiddento sidebar and header so printed dashboards show only content. - Keep sidebar nav items to 7 or fewer top-level groups; use collapsible sections for more.
Anti-Patterns
- Fixed pixel widths everywhere: Using
w-[247px]instead of design tokens likew-64makes layouts brittle. Stick to Tailwind's spacing scale. - Hiding mobile nav entirely: Removing navigation on mobile forces users to guess how to navigate. Always provide a hamburger menu or bottom nav.
- Nesting scrollable containers: A scrollable sidebar inside a scrollable page inside a scrollable modal creates scroll-trapping. Limit scroll to one axis per container.
- Header taller than 64px: Tall headers eat into content area. Keep headers slim; move secondary actions to dropdowns.
- No loading skeleton for the shell: Showing a blank screen while the sidebar loads causes layout shift. Render the shell immediately with skeleton content.
Install this skill directly: skilldb add ux-design-patterns-skills
Related Skills
Data Table UX Patterns
Data table UX patterns for sorting, filtering, pagination, bulk actions, and empty states
Form Design Patterns
Form design patterns for validation, multi-step forms, inline editing, and error handling
Modal & Dialog UX Patterns
Modal and dialog UX patterns for confirmations, form modals, drawers, and command palettes
Navigation Patterns
Navigation patterns including breadcrumbs, tabs, command palette, and sidebar collapse
Notification System Patterns
Toast, banner, badge, and inbox-style notification patterns
Onboarding Flow Patterns
User onboarding patterns with setup wizards, progressive disclosure, and empty states