Skip to content
Documentation

Layout

Layout primitives

Container, Section, Stack, Cluster, Grid and Split: the building blocks every page layout is made of.

CSS only components/layout.css

Stack, Cluster, Grid, Split

Clusterwrapswhen needed
Grid 1 → 3GridGrid
SideMain (stacks below desktop)

Section, tone sunken, narrow container

Stack, Cluster, Grid, Split
<div class="dsgn-stack">
  <div class="dsgn-cluster"><span class="docs-box">Cluster</span><span class="docs-box">wraps</span><span class="docs-box">when needed</span></div>
  <div class="dsgn-grid" data-cols="1" data-cols-tablet="3"><span class="docs-box">Grid 1 → 3</span><span class="docs-box">Grid</span><span class="docs-box">Grid</span></div>
  <div class="dsgn-split" data-side="start" style="--side: 10rem"><span class="docs-box">Side</span><span class="docs-box">Main (stacks below desktop)</span></div>
</div>
<section class="dsgn-section" data-tone="sunken" style="--dsgn-section-pad-y: var(--dsgn-space-24)"><div class="dsgn-container" data-width="narrow"><p class="dsgn-body-s">Section, tone sunken, narrow container</p></div></section>

Usage

They only place things; they draw nothing. Everything spacing-related comes from tokens, the page-level ones change at the breakpoints (tablet ≥ 40rem, desktop ≥ 64rem).

Container max width + page margin <div class="dsgn-container" data-width="narrow|full"> Section vertical page rhythm <section class="dsgn-section" data-tone="raised|sunken|accent"> Stack vertical, gap <div class="dsgn-stack" data-gap="xs|s|m|l|xl"> Cluster wrapping row <div class="dsgn-cluster" data-justify="between|end|center"> Grid columns per breakpoint <div class="dsgn-grid" data-cols="1" data-cols-tablet="2" data-cols-desktop="4"> or as many as fit <div class="dsgn-grid" data-cols="auto" style="--min: 16rem"> child spans: data-span="full" (all columns), "2" (tablet+), "3" (desktop+); data-span-desktop="1" resets Split main + side panel <div class="dsgn-split" data-side="start|end" style="--side: 20rem"> two halves (a hero) <div class="dsgn-split" data-side="half" data-gap="xl"> — stacked below desktop; data-gap as on Stack (default: grid gap). A hero uses xl, so the gap between content and media stays larger than the gaps inside the content (l) when they stack on mobile. Visibility data-hide-below="tablet|desktop" · data-hide-above="mobile|tablet"

A dark band is just a theme switch on the section: <section class="dsgn-section" data-theme="dark" data-tone="base">.

Details

Classes
.dsgn-container .dsgn-section .dsgn-stack .dsgn-cluster .dsgn-grid .dsgn-split .dsgn-table-wrap
Tokens used
--dsgn-accent-subtle --dsgn-border --dsgn-border-width --dsgn-container-max --dsgn-container-narrow --dsgn-control-gap --dsgn-grid-gap --dsgn-page-margin --dsgn-section-pad-y --dsgn-space-24 --dsgn-space-4 --dsgn-space-48 --dsgn-space-64 --dsgn-space-8 --dsgn-stack --dsgn-surface-base --dsgn-surface-raised --dsgn-surface-sunken --dsgn-text
In Figma
Section · Grid · Split
Import alone
dsgn.systems/components/layout.css