defuss-shadcn / Guides / Sizing / spacing
Spacing
One arithmetic spacing scale for gaps, padding and margins, with optional density and direction-aware helpers.
On this page (10)
§Spacing on the same base
Gaps, padding and margins use n × --size-base × --layout-density. Density is 1 by default. gap-4 therefore matches 1rem at the default base; w-4 remains geometric when density changes. The px suffix always means one CSS pixel and is not density-scaled. Below, the three everyday jobs of spacing: gap-2 between related actions, gap-6 between independent cards, p-6 inside a card.
§The box model, labeled
Every spacing utility addresses one zone of the box model: m-* works outside the border (against siblings), p-* inside it (against content). The physical sides (t/r/b/l) never move; the logical sides (s/e) follow the writing direction. The diagram uses ordinary CSS colors to make the zones visible - the classes label what each zone is.
§Gap axes
gap-x-* sets column-gap, gap-y-* sets row-gap - the two axes are independent. A calendar makes that tangible: days of a week sit gap-x-3 apart while the weeks stack tightly at gap-y-1.
The same split works for masonry-like walls and tag clouds: keep rows tight (gap-y-2) so they read as one group, and let columns spread (gap-x-6) so entries don't collide.
§Padding families
Padding shares the numeric scale with gap. p-* pads all four sides; px-* and py-* pad the inline and block axes independently - the recipe for chips, badges and inputs; a single-side helper like pt-* adds space in one direction, useful for optical alignment against a divider or media edge. The dashed outline marks the box edge: the band between it and the filled content is the padding.
§Centering and pushing with margins
Automatic margins absorb spare space. mx-auto on a fixed-width box centers it in its container - the classic content column. ms-auto on one flex item pushes it, and everything after it, to the inline end - the standard right-aligned toolbar action. Negative margins and margin-based space-x/y shortcuts are intentionally omitted.
§Physical vs logical sides
The axis families already follow the writing mode - px-* is padding-inline, py-* is padding-block. For single sides there are two families: physical pt/pr/pb/pl-* always hit the same physical edge, while logical ps/pe-* follow inline-start and inline-end. The same classes render below in dir="ltr" and in dir="rtl": the logical box mirrors with the direction, the physical box does not move. The filled band is the content box; the empty bands are the padding.
§Spacing families
Every family in this table is demonstrated in the sections before it.
| Classes | CSS property |
|---|---|
gap-*, gap-x-*, gap-y-* | gap, column-gap, row-gap |
p-*, m-* | padding, margin |
px-*, mx-* | padding-inline, margin-inline |
py-*, my-* | padding-block, margin-block |
pt/pr/pb/pl-*, mt/mr/mb/ml-* | Physical top/right/bottom/left. |
ps/pe-*, ms/me-* | Logical inline-start/inline-end. |
m/mx/my/mt/mr/mb/ml/ms/me-auto | Automatic margins. |
Every family shares the numeric scale - rendered bar by bar on Width & Height - plus px. Negative margins and margin-based space-x/y shortcuts are intentionally omitted. Gap does not create outer margins and works with wrapping layouts.
§Real world: a receipt
A whole component on one rhythm: p-6 around the card, stack gap-3 between line items, ms-auto to push amounts right, and mt-4 pt-4 with a top border to separate the total. No custom CSS anywhere.
§Custom gaps and cascade
<div class="stack" style="--layout-gap:clamp(1rem, 2vw, 2rem);"> <p>First block</p> <p>Second block</p></div>A --layout-gap override configures a layout primitive. An explicit gap-* helper overrides that primitive default. To override a helper, use normal unlayered application CSS. Avoid conflicting helpers; class-attribute order does not determine CSS precedence. Existing documentation helpers are unlayered and will win unless removed or isolated.
§Platform references
CSS cascade layers · CSS logical properties
Comments, ideas or improvements? Edit this page's source on GitHub