Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
← All tutorials · ~10 minutes · Layer focus: data-*
Build a complete marketing page with a hero, features grid, and footer. Every layout comes from data-* attributes on semantic HTML — we don't reach for a single web component.
Start with the simplest possible markup. Real HTML elements only; no classes, no attributes beyond what the platform already ships. This version works in a text-only browser.
<header> <a href="/">Acme</a> <nav> <a href="#features">Features</a> <a href="#pricing">Pricing</a> <a href="#contact">Contact</a> </nav></header> <main> <section> <h1>Build products customers love</h1> <p>The all-in-one platform that helps modern teams ship faster.</p> <nav> <a href="#signup">Start free</a> <a href="#demo">Watch demo</a> </nav> </section> <section id="features"> <h2>Why teams pick Acme</h2> <ul> <li><h3>Fast by default</h3><p>Sub-second page loads.</p></li> <li><h3>Accessible by default</h3><p>ARIA patterns built in.</p></li> <li><h3>Themeable by default</h3><p>30+ themes ship in the box.</p></li> </ul> </section></main> <footer> <small>© 2026 Acme</small> <nav><a href="#">Privacy</a> <a href="#">Terms</a></nav></footer>
The page functions already. Search engines can read it, screen readers can navigate it, and links work. Styling is the next layer, not a prerequisite.
data-layout attributesThe same elements, now with layout attributes that turn every semantic region into a flex/grid container. No wrapper divs, no utility classes.
<header data-layout="cluster" data-layout-justify="between" data-layout-align="center"> <a href="/">Acme</a> <nav data-layout="cluster" data-layout-gap="m"> <a href="#features">Features</a> <a href="#pricing">Pricing</a> <a href="#contact">Contact</a> </nav></header> <main> <section data-layout="center" data-layout-max="wide" data-layout-gap="l"> <h1>Build products customers love</h1> <p class="lead">The all-in-one platform that helps modern teams ship faster.</p> <nav data-layout="cluster" data-layout-justify="center" data-layout-gap="s"> <a href="#signup" class="button">Start free</a> <a href="#demo" class="button secondary">Watch demo</a> </nav> </section> <section id="features" data-layout="center" data-layout-max="wide" data-layout-gap="l"> <h2>Why teams pick Acme</h2> <ul data-layout="grid" data-layout-min="220px" data-layout-gap="l"> <li><h3>Fast by default</h3><p>Sub-second page loads.</p></li> <li><h3>Accessible by default</h3><p>ARIA patterns built in.</p></li> <li><h3>Themeable by default</h3><p>30+ themes ship in the box.</p></li> </ul> </section></main> <footer data-layout="cluster" data-layout-justify="between"> <small>© 2026 Acme</small> <nav data-layout="cluster" data-layout-gap="m"> <a href="#">Privacy</a> <a href="#">Terms</a> </nav></footer>
Four layout primitives did all the work: cluster for horizontal rows, center for page-width constraint, grid for the responsive features list, and stack (implicit in the defaults) for vertical rhythm. Every attribute reads like the intent it expresses.
Data attributes handle layout. When the visual shape of an element matters — a card with a consistent surface and padding — upgrade to a custom element like <layout-card>. You still use semantic HTML inside.
<ul data-layout="grid" data-layout-min="220px" data-layout-gap="l"> <li> <layout-card data-variant="outlined" data-padding="l"> <h3>Fast by default</h3> <p>Sub-second page loads, measured in production.</p> </layout-card> </li> <li> <layout-card data-variant="outlined" data-padding="l"> <h3>Accessible by default</h3> <p>ARIA patterns and keyboard support out of the box.</p> </layout-card> </li> <li> <layout-card data-variant="outlined" data-padding="l"> <h3>Themeable by default</h3> <p>Flip a single attribute and 30+ themes re-skin everything.</p> </layout-card> </li></ul>
<layout-card> is CSS-only. It adds the border, radius, and padding we'd otherwise write ourselves — no JavaScript, no hydration cost.
A marketing page rarely needs JavaScript. Everything above — the layout, the spacing, the hover states on buttons and links — ships in the CSS bundle. Adding <tab-set> or <accordion-wc> just because they're available would add weight for no reader benefit.
If you want a scripted demo reel or an inline contact form, that's the Contact form tutorial. For a pure marketing page, you're done.
data-layout="cluster" groups elements horizontally with wrap.data-layout="center" data-layout-max="wide" constrains content width and centers the section.data-layout="grid" data-layout-min="220px" auto-fits columns — no media queries.<layout-card> gives you a themed surface without a wrapper <div>.