data-layout
Apply powerful layouts to semantic HTML elements using data attributes. An alternative to custom elements with better accessibility and HTML validation.
Core Layouts
Fundamental layout patterns for everyday use.
Stack
Vertical layout with consistent gaps. The foundation of vertical rhythm.
Article Title
First paragraph of content goes here.
Second paragraph continues the story.
| Attribute | Values | Description |
|---|---|---|
data-layout-gap | none, 3xs-3xl | Spacing between items |
data-layout-align | start, center, end, stretch | Cross-axis alignment |
Cluster
Horizontal layout with wrapping. Perfect for navigation, tags, and button groups.
| Attribute | Values | Description |
|---|---|---|
data-layout-gap | xs-xl | Spacing between items |
data-layout-justify | start, end, center, between | Main axis distribution |
data-layout-align | start, end, center, stretch, baseline | Cross-axis alignment |
data-layout-nowrap | boolean | Prevent wrapping |
data-layout-overlap | xs-l | Overlap items (avatar stacks) |
Grid
Responsive auto-fit grid. Items automatically wrap based on minimum width.
| Attribute | Values | Description |
|---|---|---|
data-layout-min | 6rem-25rem, 150px, 200px, 250px, 280px, 300px, 400px | Minimum item width (rem or px) |
data-layout-gap | none, xs-xl | Spacing between items |
data-layout-subgrid | boolean | Align child internals (header/content/footer) across siblings |
Subgrid alignment
Add data-layout-subgrid to a grid container to share row tracks across children. When cards have varied content lengths, their headers, bodies, and footers align at the same height across the row. See the subgrid demo →
Center
Horizontally centered container with max-width constraint.
Centered content with controlled width. Perfect for article layouts and readable text.
| Attribute | Values | Description |
|---|---|---|
data-layout-max | narrow, normal, wide, prose | Maximum width |
data-layout-gutter | none, s, l | Horizontal padding |
data-layout-gap | none, 3xs-3xl | Vertical spacing between children (switches to flex column) |
data-layout-intrinsic | boolean | Center based on content width |
data-layout-text | boolean | Also center text alignment |
When data-layout-gap is present on a center element, it switches from display: block to display: flex; flex-direction: column. This enables vertical spacing between children without needing a nested stack. Accepted values: none, 3xs, 2xs, xs, s, m, l, xl, 2xl, 3xl.
Sidebar
Two-column layout with flexible sidebar. Semantic-aware: nav/aside become sidebar, main/article become content.
Main content area
| Attribute | Values | Description |
|---|---|---|
data-layout-side | start (default), end | Sidebar position |
data-layout-sidebar-width | narrow, normal, wide | Sidebar width |
data-layout-content-min | 40, 50, 60 | Content min-width % |
data-layout-gap | xs-xl | Gap between sidebar and content |
data-layout-nowrap | boolean | Prevent stacking on mobile |
Split
Two-column ratio-based layout. Great for hero sections and content with media.
| Attribute | Values | Description |
|---|---|---|
data-layout-ratio | 1:2, 2:1, 1:3, 3:1, golden | Column ratio |
data-layout-gap | s-xl | Gap between columns |
data-layout-align | start, center, end, stretch | Vertical alignment |
data-layout-fill | boolean | Full viewport height (100dvh), ideal for sign-in pages |
Special Layouts
Cover
Full-height container with vertically centered principal element. Perfect for hero sections.
| Attribute | Values | Description |
|---|---|---|
data-layout-min | 50vh, 75vh, 100vh, 100dvh, auto | Minimum height |
data-layout-padding | none, s-xl | Internal padding |
data-layout-centered | boolean | Center align contents |
data-layout-principal | child attribute | Mark the centered element |
Switcher
Flexbox layout that switches from horizontal to vertical at a threshold width.
| Attribute | Values | Description |
|---|---|---|
data-layout-threshold | 20rem-45rem | Switch breakpoint |
data-layout-gap | none, xs-xl | Spacing between items |
data-layout-limit | 2, 3, 4 | Max items before forcing vertical |
data-layout-reverse | boolean | Reverse item order |
Prose
Typography utility for readable text content with controlled line length.
| Attribute | Values | Description |
|---|---|---|
data-layout-max | narrow (45ch), normal (65ch), wide (80ch) | Maximum line length |
data-layout-centered | boolean | Center the prose block |
Regions
Generalized header / content / footer grid. Semantic children auto-place without explicit attributes. Full documentation →
| Attribute | Values | Description |
|---|---|---|
data-layout-gap | none, 3xs-3xl | Spacing between regions |
Media
Figure + content side by side (the media object pattern). Full documentation →
| Attribute | Values | Description |
|---|---|---|
data-layout-gap | none, xs-xl | Gap between figure and content |
data-layout-reverse | boolean | Content on left, figure on right |
data-layout-align | start, center, end, stretch | Vertical alignment |
Layout Composition
The data-layout attribute applies layout behavior to any HTML element. Instead of wrapping content in custom element tags like <layout-stack> or <layout-center>, you can use semantic HTML elements with data attributes. This reduces nesting and improves accessibility.
The data-layout attribute
Add data-layout="center", data-layout="stack", data-layout="grid", or any other layout name to turn a plain HTML element into a layout container. All the same modifier attributes (data-layout-gap, data-layout-max, data-layout-min, etc.) work exactly as they do on the custom elements.
Before and after
Using data attributes, you can often eliminate wrapper elements entirely. Center with gap replaces the need for a center wrapping a stack, because data-layout-gap on a center element automatically enables flex-column spacing.
Before: custom element wrappers
After: semantic HTML with data attributes
The "after" version uses a single <section> that is both centered and vertically spaced, removing an entire layer of nesting. The grid is a plain <div> instead of a custom element.
Visual components remain as custom elements
Layout attributes replace structural wrappers (<layout-center>, <layout-stack>, <layout-grid>, etc.). Visual components that carry their own styles and behavior — such as <layout-card>, <layout-badge>, and <layout-text> — remain as custom elements because they encapsulate appearance, not just layout.
Responsive Behavior
All page layouts automatically collapse to a single column on viewports narrower than 768px, unless data-layout-nowrap is set.
Container Queries
Semantic sections (main, article, section, aside) have container queries enabled. Nested layouts can respond to their container width, not just viewport.
Scroll-driven header shrink
Add data-scroll-shrink to a sticky page header to compress its padding and font size as the user scrolls. Uses animation-timeline: scroll() (Chrome 115+, Firefox 110+). Browsers without support show a static sticky header. See the scroll shrink demo →
Animatable radius tokens
The design tokens --radius-s, --radius-m, and --radius-l are registered via @property with syntax: "<length>", enabling smooth CSS transitions between radius values. Without registration, custom property transitions snap instantly. See the @property radius demo →