Semantic Layouts
Use data-layout attributes on semantic HTML elements instead of custom element wrappers. Same CSS, same behavior, better semantics.
Why Semantic Layouts
Vanilla Breeze layout primitives work on any element, not just custom elements. Using them on semantic HTML gives you the same layouts with additional benefits.
Fewer Nesting Levels
Combine center + gap on a single element instead of nesting center inside stack. Less indentation, easier to scan.
Better Accessibility
HTML validators and screen readers understand <section>, <header>, and <article> natively. No extra ARIA needed.
LLM-Friendly Markup
AI tools parse semantic HTML better than custom elements. Your code is more understandable to both humans and machines.
Same CSS, Same Behavior
The data-layout attributes use the exact same CSS as the custom elements. Nothing changes except the tag name.
Two Approaches, Same CSS
Every layout primitive in Vanilla Breeze can be used as either a custom element or a data attribute on any HTML element.
| Layout | Custom Element | Data Attribute |
|---|---|---|
| Stack | <layout-stack> |
data-layout="stack" |
| Center | <layout-center> |
data-layout="center" |
| Grid | <layout-grid> |
data-layout="grid" |
| Cluster | <layout-cluster> |
data-layout="cluster" |
| Sidebar | <layout-sidebar> |
data-layout="sidebar" |
| Cover | <layout-cover> |
data-layout="cover" |
| Switcher | <layout-switcher> |
data-layout="switcher" |
All data-layout attributes (gap, min, max, align, justify) work identically on both custom elements and semantic elements. The only difference is the tag name in your HTML.
Side-by-Side Comparison
Custom Elements
Semantic HTML
<section> and <header> instead of generic wrappers. Screen readers announce these landmarks automatically. The data-layout-gap on center also eliminates the need for a nested stack.
Building a Feature Section
Let us transform a real feature section from custom elements to semantic HTML, one step at a time.
The Starting Point
Here is a typical feature section built with custom element wrappers. It works, but notice how many nesting levels are required.
Step 1: Replace layout-center + layout-stack
The outermost <layout-center> wrapping a <layout-stack> is a common pattern. With data attributes, we can combine both behaviors on a single <section> element by using data-layout="center" with data-layout-gap.
Step 2: Replace the inner layout-stack
The heading group is naturally a <header> element. We apply data-layout="stack" directly to it.
Step 3: Replace layout-grid
The grid wrapper becomes a plain <div> with data-layout="grid". Each feature item also gets data-layout="stack".
The Result
The semantic version is flatter, uses real HTML landmarks, and produces the exact same visual result. Every data-layout attribute maps to the same CSS rules as its custom element counterpart.
The Center + Gap Pattern
The most common refactoring: eliminating a nested stack inside a center element.
In Vanilla Breeze, when data-layout-gap is added to a center element, the center switches from display: block to display: flex; flex-direction: column with the specified gap. This means a single element can both center its content and space its children vertically.
Before: Two Elements
After: One Element
[data-layout="center"][data-layout-gap] activates display: flex; flex-direction: column, turning the center into a flex container with vertical gap. This is the same behavior as layout-center[data-layout-gap] on the custom element.
Common Compositions
Here are the most useful semantic layout patterns you will reach for regularly.
Center + Gap (replaces center > stack)
The most common pattern. Use on <section>, <main>, or <article> to center content with vertical spacing.
Sidebar on Article or Section
The sidebar layout is semantic-aware: it automatically recognizes <nav> and <aside> as sidebar elements and <main>, <article>, <section> as content elements.
Grid on a Div
Use data-layout="grid" on a plain div to create responsive grids. Visual components like <layout-card> remain as custom elements inside.
Cover on Body or Main
The cover layout vertically centers a principal element. Use data-layout-principal on the child you want centered.
Cluster on a Div for Button Groups
Use data-layout="cluster" for horizontal groups of items that wrap naturally.
When to Keep Custom Elements
Not everything should become a data attribute. Visual components always stay as custom elements.
The key distinction is between layout primitives and visual components:
- Layout primitives (stack, center, grid, cluster, sidebar, cover, switcher) control spacing and arrangement. These are good candidates for
data-layoutattributes. - Visual components (card, badge, text, brand-mark, form-field) provide visual styling like shadows, borders, backgrounds, and typography. These should remain as custom elements.
In this example, the grid is a data attribute (layout concern), while cards and badges remain as custom elements (visual concern). This is the recommended pattern: semantic HTML for structure, custom elements for styled components.
data-layout on a semantic element.
Decision Guide
Use this table to decide which approach fits your situation.
| Scenario | Recommended Approach | Why |
|---|---|---|
| Quick prototyping | Custom elements | Fastest to type, self-documenting tag names |
| Simple page, minimal nesting | Either | Both work well when structure is shallow |
| Production code | Data attributes | Better semantics, cleaner HTML, fewer nesting levels |
| Complex nested layouts | Data attributes | Significantly reduces nesting depth |
| Accessibility-sensitive context | Data attributes | Screen readers understand native landmarks |
| Working with LLMs or AI tools | Data attributes | Standard HTML is better understood by AI |
| Visual components (card, badge) | Custom elements | These provide styling, not just layout |
| Teaching HTML concepts | Custom elements | Tag names make the layout intent explicit |
You can freely mix both approaches in the same page. Use custom elements where they make the code clearer and data attributes where they reduce unnecessary nesting. The CSS is the same either way.
Page Layouts & Grid Identity
Semantic layouts extend beyond component-level patterns to full page structure with the grid identity system.
VB includes a three-tier grid identity system where semantic HTML elements auto-register to grid areas based on their element type. At the page level, data-page-layout on the <body> turns <header>, <nav>, <main>, <aside>, and <footer> into grid areas automatically — no classes needed.
At the component level, data-layout="regions" generalizes the header/content/footer pattern to any element, and data-layout="media" provides a figure+content media object. These compose with page layouts for full three-tier nesting.