layout: content layouts
Six content patterns, each shown wrong (the container pads) and right (only leaves pad). Containers query their own width with container queries, not the viewport. Tick the inspector to see who owns padding.
reading column and breakouts
Three grid tracks: the middle one caps the measure at 40rem, the outer ones absorb breakouts.
A: the article pads
the reading track keeps the measure comfortable. a padded container cannot express that: everything inside shares one inset.
prose after the figure.
closing prose.
every breakout drags a negative margin, and the measure is padding-dependent: change the inset and the line length changes.
B: the leaves pad
the reading track keeps the measure at 40rem no matter how wide the frame gets. breakouts span the other tracks.
prose resumes in the track.
closing prose.
the grid owns arrangement, leaves own padding. bleed is a span, not a margin.
Reading measure is a grid track (minmax with 0!), not a padding side effect. Breakouts change col-span; they never cancel padding.
<div className="grid grid-cols-[1fr_minmax(0,40rem)_1fr] gap-y-4"><div className="col-span-3 …">hero · full bleed</div> {/* breakout: spans all 3 tracks */}<p className="col-start-2 px-4">…</p> {/* leaf: track 2, pads itself */}<div className="col-span-3 border-l-4 …">note</div> {/* breakout leaf: spans + pads */}</div>
landing
Hero, feature grid, cta band. The landing queries its own width: drag the slider and the feature columns re-flow.
A: the landing pads
one rule: containers arrange, leaves pad.
the cta band needs negative margins to touch the rounded edges, and the hero gradient stops at the padding.
B: the leaves pad
one rule: containers arrange, leaves pad.
the band is a container: it stretches edge to edge and its leaves pad inside it. the hero fill reaches the top because the landing pads nothing: the hero button is inset by a spacer row, the band button by a spacer track.
Full-bleed bands and hero fills are the first sign a container pads. On the leaf-padded side they are free.
<div className="@container flex flex-col overflow-hidden rounded-xl"> {/* bands only, zero padding */}<div className="flex flex-col items-center after:h-10 after:content-['']"> {/* band; leaves inset */}<b className="px-6 pt-10">…</b><Button size="sm">get started</Button></div><div className="mt-8 grid grid-cols-[1fr_auto_auto] items-center after:w-8 after:content-['']"> {/* spacer track */}<b className="px-8 py-6">ready?</b><Button variant="outline">start free</Button></div></div>
pricing tiers
The ribbon and the foot are part of the card surface, so the card cannot pad.
A: the tier pads
ribbon and foot fight the padding with negative margins; the featured card's border shifts everything inside by 2px.
B: the leaves pad
ribbon and foot are leaves: they pad themselves and sit flush against the card edges. the featured outline is a ring, so it shifts nothing inside.
Ribbon and foot are surface leaves: they cannot exist inside padding, so the tier never pads. The button is inset by a spacer row; a featured outline is a ring, which draws without shifting layout.
<div className="flex flex-col overflow-hidden rounded-xl"> {/* container: zero padding */}<div className="bg-indigo-500 px-6 py-1 text-center text-xs">most popular</div> {/* leaf: flush */}<b className="px-6 pt-3 text-2xl">$20</b> {/* leaf: pads itself */}<Button size="sm">choose</Button></div>{/* button inset: spacer row, not margin; featured outline: inset ring */}<div className="… after:h-6 after:content-['']" /><div className="… ring-2 ring-inset ring-indigo-500" />
docs layout
Nav, content, toc. The active nav item's indicator sits on the pane edge, so the nav cannot pad.
A: the columns pad
containers arrange, leaves pad.
pnpm add tailwindcss
the active item's left indicator is stranded inside the padding; the code block needs a negative margin to touch both pane edges.
B: the leaves pad
containers arrange, leaves pad.
pnpm add tailwindcss
the indicator hugs the pane edge; the code block is a leaf with its own padding.
Any indicator or rail drawn on a pane edge (active borders, toc rules) requires an unpadded pane. Padding would strand it.
<div className="flex overflow-hidden rounded-xl"> {/* container: three panes, zero padding */}<nav className="flex w-48 shrink-0 flex-col border-r"> {/* pane: unpadded so the rail hugs the edge */}<span className="border-l-2 border-indigo-400 px-4 py-1">layout</span></nav><div className="flex min-w-0 flex-1 flex-col gap-3"><p className="overflow-x-auto bg-zinc-950 px-6 py-3">pnpm add tailwindcss</p> {/* leaf: pads itself */}</div></div>
feed and timeline
The rail is a grid column, not an absolutely positioned line hunting for dots by magic offsets.
A: absolute rail
the rail guesses its offsets from the padding; move anything and the dots drift off the line.
B: rail as a column
2m ago
18m ago
1h ago
each row is one grid: the rail cell draws top-cap, dot, and the rest of the line. the line cannot miss the dot.
Absolutely positioned connectors are a smell. If a line must pass through dots, give the dots a shared column and let the column draw the line.
<div className="grid grid-cols-[2.5rem_1fr]"> {/* one grid per row: rail column + text */}<span className="flex flex-col items-center"> {/* the column draws the line */}<span className="h-4 w-px bg-zinc-700" /><span className="size-2 rounded-full" /><span className="w-px flex-1 bg-zinc-700" /></span><span className="py-2 pr-4"><b>deploy 47 passed</b></span> {/* leaf pads itself; no absolute rail */}</div>
kanban
Horizontal scroll; the sticky column header sits flush because the column, not the board, is the header's container. Resize the board and drag it sideways.
A: the board pads
the sticky header never reaches the column's rounded top: the board padding and column padding both get in the way.
B: the columns pad
the header is the column's first leaf: sticky, flush with the rounded top. the body insets its cards with gutter tracks, not margins.
The sticky header is why the column cannot pad: a padded column pushes the sticky fill off the rounded edge. The scroll body arranges cards with gutter tracks, so cards inset without margins.
<div className="flex w-56 shrink-0 flex-col overflow-hidden rounded-lg"> {/* column: zero padding */}<div className="bg-zinc-700 px-3 py-2">todo · 3</div> {/* first leaf: sticky, flush with the top */}<div className="grid flex-1 grid-cols-[0.75rem_minmax(0,1fr)_0.75rem] gap-y-2before:col-span-3 before:h-2 before:content-['']after:col-span-3 after:h-2 after:content-['']"> {/* gutter tracks + spacer rows */}<div className="col-start-2 rounded-md bg-zinc-950 px-3 py-2">card a</div></div></div>