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.

<article data-layout="stack" data-layout-gap="m"> <h2>Article Title</h2> <p>First paragraph...</p> <p>Second paragraph...</p> </article>
Attribute Values Description
data-layout-gapnone, 3xs-3xlSpacing between items
data-layout-alignstart, center, end, stretchCross-axis alignment

Cluster

Horizontal layout with wrapping. Perfect for navigation, tags, and button groups.

<nav data-layout-justify="center"> <ul data-layout="cluster" data-layout-gap="s"> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> <li><a href="/contact">Contact</a></li> </ul> </nav>
Attribute Values Description
data-layout-gapxs-xlSpacing between items
data-layout-justifystart, end, center, betweenMain axis distribution
data-layout-alignstart, end, center, stretch, baselineCross-axis alignment
data-layout-nowrapbooleanPrevent wrapping
data-layout-overlapxs-lOverlap items (avatar stacks)

Grid

Responsive auto-fit grid. Items automatically wrap based on minimum width.

Card 1
Card 2
Card 3
Card 4
<section data-layout="grid" data-layout-min="15rem" data-layout-gap="m"> <article>Card 1</article> <article>Card 2</article> <article>Card 3</article> </section>
Attribute Values Description
data-layout-min6rem-25rem, 150px, 200px, 250px, 280px, 300px, 400pxMinimum item width (rem or px)
data-layout-gapnone, xs-xlSpacing between items
data-layout-subgridbooleanAlign 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.

<main data-layout="center" data-layout-max="prose"> <h1>Centered Content</h1> <p>This content is centered with a comfortable reading width...</p> </main>
Attribute Values Description
data-layout-maxnarrow, normal, wide, proseMaximum width
data-layout-gutternone, s, lHorizontal padding
data-layout-gapnone, 3xs-3xlVertical spacing between children (switches to flex column)
data-layout-intrinsicbooleanCenter based on content width
data-layout-textbooleanAlso 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.

Two-column layout with flexible sidebar. Semantic-aware: nav/aside become sidebar, main/article become content.

Main content area

<div data-layout="sidebar" data-layout-sidebar-width="wide"> <nav>Sidebar navigation...</nav> <main>Main content area...</main> </div>
Attribute Values Description
data-layout-sidestart (default), endSidebar position
data-layout-sidebar-widthnarrow, normal, wideSidebar width
data-layout-content-min40, 50, 60Content min-width %
data-layout-gapxs-xlGap between sidebar and content
data-layout-nowrapbooleanPrevent stacking on mobile

Split

Two-column ratio-based layout. Great for hero sections and content with media.

Attribute Values Description
data-layout-ratio1:2, 2:1, 1:3, 3:1, goldenColumn ratio
data-layout-gaps-xlGap between columns
data-layout-alignstart, center, end, stretchVertical alignment
data-layout-fillbooleanFull viewport height (100dvh), ideal for sign-in pages

Special Layouts

Cover

Full-height container with vertically centered principal element. Perfect for hero sections.

<section data-layout="cover" data-layout-min="100vh" data-layout-centered> <header>Top content</header> <div data-layout-principal> <h1>Hero headline centered vertically</h1> </div> <footer>Bottom content</footer> </section>
Attribute Values Description
data-layout-min50vh, 75vh, 100vh, 100dvh, autoMinimum height
data-layout-paddingnone, s-xlInternal padding
data-layout-centeredbooleanCenter align contents
data-layout-principalchild attributeMark the centered element

Switcher

Flexbox layout that switches from horizontal to vertical at a threshold width.

Attribute Values Description
data-layout-threshold20rem-45remSwitch breakpoint
data-layout-gapnone, xs-xlSpacing between items
data-layout-limit2, 3, 4Max items before forcing vertical
data-layout-reversebooleanReverse item order

Prose

Typography utility for readable text content with controlled line length.

Attribute Values Description
data-layout-maxnarrow (45ch), normal (65ch), wide (80ch)Maximum line length
data-layout-centeredbooleanCenter the prose block

Regions

Generalized header / content / footer grid. Semantic children auto-place without explicit attributes. Full documentation →

Attribute Values Description
data-layout-gapnone, 3xs-3xlSpacing between regions

Media

Figure + content side by side (the media object pattern). Full documentation →

Attribute Values Description
data-layout-gapnone, xs-xlGap between figure and content
data-layout-reversebooleanContent on left, figure on right
data-layout-alignstart, center, end, stretchVertical 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

<layout-center data-layout-max="wide"> <layout-stack data-layout-gap="xl"> <h2>Title</h2> <layout-grid data-layout-min="250px"> <div>Card 1</div> <div>Card 2</div> <div>Card 3</div> </layout-grid> </layout-stack> </layout-center>

After: semantic HTML with data attributes

<section data-layout="center" data-layout-max="wide" data-layout-gap="xl"> <h2>Title</h2> <div data-layout="grid" data-layout-min="250px"> <div>Card 1</div> <div>Card 2</div> <div>Card 3</div> </div> </section>

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 →