Patterns
Shells
Shells
Application shell layouts for web apps, dashboards, and admin interfaces. Header, sidebar, and content area patterns.
Overview
App shells define the overall structure of your application, organizing navigation, content areas, and auxiliary panels. Choose a layout based on your application's navigation needs and content complexity.
Key features:
Semantic HTML5 structure with header, nav, main, and aside
Responsive layouts that adapt to different screen sizes
Flexible content areas using layout primitives
Accessible navigation patterns with proper ARIA labels
Stacked Layout
The traditional layout with a header on top and main content below. Best for content-focused applications where vertical space is important.
<body data-page-layout="stack" data-layout-gap="none">
<header data-layout="cluster" data-layout-justify="between">
<a href="/vanilla-breeze/"><brand-mark>AppName</brand-mark></a>
<nav class="horizontal pills" aria-label="Main navigation">
<ul>
<li><a href="/vanilla-breeze/dashboard" aria-current="page">Dashboard</a></li>
<li><a href="/vanilla-breeze/projects">Projects</a></li>
<li><a href="/vanilla-breeze/reports">Reports</a></li>
<li><a href="/vanilla-breeze/settings">Settings</a></li>
</ul>
</nav>
<div data-layout="cluster" data-layout-gap="s">
<button class="button small icon-only" aria-label="Notifications">
<icon-wc name="bell"></icon-wc>
</button>
<button class="button small icon-only" aria-label="User menu">
<icon-wc name="user"></icon-wc>
</button>
</div>
</header>
<main>
<div data-layout="center" data-layout-max="wide">
<div data-layout="stack" data-layout-gap="l">
<h1>Dashboard</h1>
<!-- Page content here -->
</div>
</div>
</main>
<footer>
<p>© 2026 AppName. All rights reserved.</p>
</footer>
</body>
Sidebar + Content
A fixed sidebar navigation with a main content area. Ideal for dashboards and admin interfaces with many navigation items.
<body data-page-layout="sidebar-left" data-layout-gap="none" data-layout-sidebar-width="narrow">
<nav data-layout="stack" data-layout-gap="l" data-layout-sticky aria-label="Main navigation">
<a href="/vanilla-breeze/"><brand-mark>AppName</brand-mark></a>
<ul class="vertical">
<li><a href="/vanilla-breeze/dashboard" aria-current="page">
<icon-wc name="home"></icon-wc> Dashboard
</a></li>
<li><a href="/vanilla-breeze/projects">
<icon-wc name="folder"></icon-wc> Projects
</a></li>
<li><a href="/vanilla-breeze/team">
<icon-wc name="users"></icon-wc> Team
</a></li>
<li><a href="/vanilla-breeze/reports">
<icon-wc name="chart-bar"></icon-wc> Reports
</a></li>
<li><a href="/vanilla-breeze/settings">
<icon-wc name="cog"></icon-wc> Settings
</a></li>
</ul>
</nav>
<main data-layout="stack" data-layout-gap="none">
<header data-layout="cluster" data-layout-justify="between">
<h1>Dashboard</h1>
<div data-layout="cluster" data-layout-gap="s">
<input type="search" placeholder="Search..." aria-label="Search" />
<button class="button icon-only" aria-label="User menu">
<icon-wc name="user"></icon-wc>
</button>
</div>
</header>
<section class="main-content">
<!-- Page content here -->
</section>
</main>
</body>
Multi-Column Layout
A three-column layout with sidebar navigation, main content, and a right panel. Perfect for email clients, chat applications, or content management systems.
<body data-page-layout="holy-grail" data-layout-gap="none" data-layout-sidebar-width="narrow">
<nav data-layout="stack" data-layout-gap="m" data-layout-sticky aria-label="Mail folders">
<a href="/vanilla-breeze/"><brand-mark data-size="l">Mail</brand-mark></a>
<button class="button primary">Compose</button>
<ul class="vertical">
<li><a href="/vanilla-breeze/inbox" aria-current="page">
<icon-wc name="inbox"></icon-wc> Inbox <layout-badge>12</layout-badge>
</a></li>
<li><a href="/vanilla-breeze/sent"><icon-wc name="paper-airplane"></icon-wc> Sent</a></li>
<li><a href="/vanilla-breeze/drafts"><icon-wc name="document"></icon-wc> Drafts</a></li>
<li><a href="/vanilla-breeze/trash"><icon-wc name="trash"></icon-wc> Trash</a></li>
</ul>
</nav>
<main data-layout="stack" data-layout-gap="none">
<header data-layout="cluster" data-layout-justify="between">
<h1>Inbox</h1>
<input type="search" placeholder="Search mail..." aria-label="Search mail" />
</header>
<ul class="messages">
<!-- Message list items -->
</ul>
</main>
<aside data-layout-sticky>
<!-- Selected message content -->
</aside>
</body>
Collapsible Sidebar
A sidebar that can collapse to icons only, using native <details> and <summary> elements. Great for maximizing content space while keeping navigation accessible.
<body data-page-layout="sidebar-left" data-layout-gap="none" data-layout-sidebar-width="narrow">
<nav aria-label="Main navigation">
<details class="sidebar" open>
<summary>
<icon-wc name="bars-3"></icon-wc>
<span class="visually-hidden">Toggle sidebar</span>
</summary>
<div class="sidebar-content" data-layout="stack" data-layout-gap="l">
<a href="#" class="logo">AppName</a>
<nav class="vertical" aria-label="Sidebar links">
<ul>
<li><a href="/vanilla-breeze/dashboard" aria-current="page">
<icon-wc name="home"></icon-wc>
<span class="nav-label">Dashboard</span>
</a></li>
<!-- more nav items -->
</ul>
</nav>
</div>
</details>
</nav>
<main data-layout="stack" data-layout-gap="none">
<header data-layout="cluster" data-layout-justify="between">
<h1>Dashboard</h1>
<!-- Header actions -->
</header>
<section class="main-content">
<!-- Page content here -->
</section>
</main>
</body>
Configuration
App shells use these layout elements and attributes:
Page Layout
Attribute
Values
Description
data-page-layout
stack sidebar-left sidebar-right holy-grail app-shell dashboard
Sets the overall page layout grid template.
data-layout-sidebar-width
narrow normal wide
Sets the sidebar column width. Default is approximately 17.5rem.
data-layout-gap
none xs s m l xl
Gap between layout regions.
data-layout-content-min
40% 50% 60%
Minimum content width before stacking. Default is 50%.
Layout Stack
Attribute
Values
Description
data-layout-gap
none xs s m l xl
Vertical spacing between stack items.
Layout Cluster
Attribute
Values
Description
data-layout-gap
none xs s m l xl
Horizontal spacing between items.
data-layout-justify
start center end between
Horizontal alignment of items.
data-layout-align
start center end stretch
Vertical alignment of items.
Usage Notes
Full height: data-page-layout handles this automatically with min-height: 100dvh
Sticky elements: Use the data-layout-sticky attribute on nav or aside elements
Responsive: data-page-layout layouts auto-stack on narrow viewports (< 768px)
Collapsible sidebar: Use <details>/<summary> inside <nav> for zero-JS collapse
Accessibility: Include skip links, proper heading hierarchy, and ARIA labels on navigation landmarks