Spacing Systems
You already know that arbitrary spacing feels wrong. When buttons have 14px padding in one place and 11px in another, users notice — even if they cannot name why. Designers use spacing tokens to prevent this. In CSS, we do exactly the same thing: commit to a spacing scale and only use values from that scale.
The 4/8px spacing system
Section titled “The 4/8px spacing system”The most widely used spacing scale is based on multiples of 4 (sometimes called a “4-point grid”) or multiples of 8 (an “8-point grid”). Every spacing value in your project comes from this sequence:
| Step | 4pt scale | 8pt scale |
|---|---|---|
| 1 | 4px | 8px |
| 2 | 8px | 16px |
| 3 | 12px | 24px |
| 4 | 16px | 32px |
| 5 | 20px | 40px |
| 6 | 24px | 48px |
In CSS it is common to express these in rem units (where 1rem = 16px by default):
| rem | px equivalent |
|---|---|
0.25rem | 4px |
0.5rem | 8px |
0.75rem | 12px |
1rem | 16px |
1.5rem | 24px |
2rem | 32px |
The three spacing properties
Section titled “The three spacing properties”padding — Space inside an element, between its border and its content. Grows the element itself. Think of the “horizontal/vertical padding” in a Figma auto-layout frame.
margin — Space outside an element, pushing away from its neighbors. Does not grow the element — it creates a buffer zone around it.
gap — Space between children in a Flex or Grid container. The cleanest, most predictable way to space items — it does not add space around the edges, only between items.
When to use each
Section titled “When to use each”| Scenario | Use |
|---|---|
| Space between items inside a flex or grid container | gap |
| Internal padding of a button, card, or box | padding |
| Push one element away from a sibling | margin |
| Center a block element horizontally | margin: 0 auto |
| Keep content away from the edges of the page | padding on the body/container |
Editable example — a card with a spacing system
Section titled “Editable example — a card with a spacing system”Things to try:
- Change
.cardpaddingfrom1.5remto0.5rem— notice how cramped it feels - Change
.pagegapfrom1remto3rem— notice how airy it becomes - Change
.actionsgapfrom0.5remto2rem— the buttons drift apart - Try
padding: 2remon.card— it expands to match