Structure
Layout Primitives
Eleven composable layouts inspired by Every Layout (Heydon Pickering & Andy Bell). Each solves exactly one spatial problem. Nest them instead of writing custom display: flex.
Rule of thumb
| When you need… | Use | Not |
|---|---|---|
| Vertical stack of elements | ren-stack | display: flex; flex-direction: column |
| Horizontal items that wrap | ren-cluster | display: flex; flex-wrap: wrap |
| Header with left + right content | ren-row-spread | justify-content: space-between |
| Centered content container | ren-center | max-width: X; margin: 0 auto |
| Responsive card grid | ren-grid ren-grid-3 | grid-template-columns: repeat(3, 1fr) |
| Sidebar + main content | ren-with-sidebar | custom flex with fixed sidebar |
| Full-screen centered (login, hero) | ren-cover | min-height: 100vh; flex center |
ren-stack
Vertical flow with consistent spacingThe most-used layout in RenDS. Any list of elements that should sit on top of each other with a gap between them. Gap defaults to --space-4 (16px).
Preview
Markup
<div class="ren-stack">
<p>First</p>
<p>Second</p>
<p>Third</p>
</div>Variants
Gap sizes: ren-stack-xs (4px), -sm (8px), -md (16px, default), -lg (24px), -xl (32px). Or override inline: style="--stack-gap: var(--space-6)".
ren-cluster
Horizontal items that wrapFor tags, buttons, chips, or any set of inline-ish elements that should flow horizontally and wrap when they run out of room.
Preview
Markup
<div class="ren-cluster">
<span class="ren-tag">Design</span>
<span class="ren-tag">Accessibility</span>
<span class="ren-tag">Tokens</span>
</div>Custom gap: style="--cluster-gap: var(--space-3)".
ren-row
Non-wrapping horizontal rowLike Cluster but never wraps. Ideal for icon + label pairs, breadcrumbs, or toolbars where you know the children fit.
Preview
Markup
<div class="ren-row">
<svg>...</svg>
<span>Label</span>
</div>ren-row-spread
Left-aligned + right-aligned contentAny header bar, card footer, or "title on the left, actions on the right" layout. Replaces the justify-content: space-between reflex.
Preview
Markup
<div class="ren-row-spread">
<h1>Dashboard</h1>
<button class="ren-btn ren-btn-primary">New</button>
</div>ren-center
Max-width container, horizontally centeredThe "content column" pattern. Wraps your main content, caps its width, keeps it centered on any viewport.
Preview
Markup
<main class="ren-center">
<h1>Article title</h1>
<p>Body copy...</p>
</main>Variants
ren-center-narrow — width-2xl, good for forms.
ren-center-prose — width-prose (~65ch), good for articles.
ren-center-wide — width-7xl, good for app shells.
ren-with-sidebar
Fixed sidebar + flexible mainEvery app layout. Sidebar at a fixed width on the left, main content fills the rest. Wraps gracefully on narrow viewports.
Preview
Markup
<div class="ren-with-sidebar" style="--sidebar-width: 260px">
<aside>...</aside>
<main>...</main>
</div>ren-grid
Responsive card gridAuto-fitting grid for cards, tiles, stat panels. Combine ren-grid with ren-grid-2, ren-grid-3, or ren-grid-4 for fixed column counts.
Preview (ren-grid-3)
Markup
<div class="ren-grid ren-grid-3">
<div class="ren-card">...</div>
<div class="ren-card">...</div>
<div class="ren-card">...</div>
</div>Plain ren-grid uses auto-fit with a min-width, perfect when you don't know how many items there will be.
ren-cover
Full-viewport centered contentLogin pages, hero sections, empty states. Content vertically centered on at least 100vh, with optional header/footer at the top/bottom.
Preview
Markup
<div class="ren-cover">
<header>...</header> <!-- optional top -->
<main class="ren-center-narrow">
<form class="ren-card">...</form>
</main>
<footer>...</footer> <!-- optional bottom -->
</div>ren-frame
Aspect-ratio containerLocks a box to a specific aspect ratio. Ideal for video embeds, thumbnails, or cover images that can't collapse on load.
Preview
Markup
<div class="ren-frame ren-frame-video">
<img src="thumb.jpg" alt="">
</div>Variants: ren-frame-square (1:1), ren-frame-video (16:9), ren-frame-photo (4:3). Custom ratio: style="--frame-ratio: 3 / 2".
ren-switcher
Row on wide, column on narrowSwitches from horizontal to vertical at a container breakpoint. The "no more media queries" way to do responsive columns.
Markup
<div class="ren-switcher">
<div>Column one</div>
<div>Column two</div>
<div>Column three</div>
</div>Threshold: style="--switcher-threshold: 40rem".
ren-reel
Horizontal scroll rowFor galleries, carousels, horizontal card lists. Scroll-snap on by default; hide the scrollbar with ren-reel-hidden-scroll if you want.
Preview
Markup
<div class="ren-reel">
<img src="1.jpg" alt="">
<img src="2.jpg" alt="">
<img src="3.jpg" alt="">
</div>Composing a full page
Most pages are two or three layouts deep. Here's a dashboard skeleton using only layout primitives — zero custom flex, zero custom grid.
<div class="ren-with-sidebar" style="--sidebar-width: 260px">
<aside><!-- sidebar nav --></aside>
<main class="ren-stack-lg">
<div class="ren-row-spread">
<h1>Dashboard</h1>
<button class="ren-btn ren-btn-primary">New</button>
</div>
<div class="ren-grid-4">
<!-- stat cards -->
</div>
<div class="ren-card">
<!-- big chart -->
</div>
<div class="ren-grid-2">
<!-- table + activity feed -->
</div>
</main>
</div>Want to see it built out? Open landing.html or blog.html — both are built entirely with these primitives.