Skip to content

Spacing Scale

Checked by spacing-scale (opt-in)

Spacing drifts. One card gets 14px of padding, the next one 16px, a third 18px because it looked tight that day. Nobody sees the 2px, but people feel that the page is slightly off, and every new screen adds another value.

Pick every space from a small scale, and let the steps grow as the gaps do.

7 values: 6, 7, 9, 10, 14, 18, 22

The two cards look almost the same. The one-off version uses seven values, each picked by eye, and the check marks sit at three different distances from their text. The scale version uses four: 4, 8, 16 and 24. Things that should line up now do, and the next person to build a card has four answers instead of seven guesses.

Steps that grow

Start from 4px: 4, 8, 12, 16, 24, 32, 48, 64. The steps are 4px apart at the bottom, then 8, then 16.

gap-61.5x the step below

We notice spacing in proportion. Going from 8px to 12px adds 50% and is easy to see. Going from 48px to 52px adds 8% and nobody would notice, so it should not be a separate choice. Each step here is between 1.33x and 2x the one below.

The 8-point grid allows only multiples of 8. I find that too coarse for dense interfaces: 4px and 12px come up constantly for icon gaps and compact rows. Atlassian builds on 8px too, but adds half steps like 4, 6 and 12 for the same reason. A 4px base covers them and still lands on every multiple of 8.

In Tailwind

Tailwind v4 derives every spacing utility from one variable, --spacing: 0.25rem, so gap-3 is 12px and p-6 is 24px. That is a 4px base, but not a scale: gap-5, p-13 and mt-4.5 all work too. Reset the namespace and name only the steps you allow.

Usage

styles.css
@import "tailwindcss";

@theme {
  --spacing-*: initial;
  --spacing-1: 4px;
  --spacing-2: 8px;
  --spacing-3: 12px;
  --spacing-4: 16px;
  --spacing-6: 24px;
  --spacing-8: 32px;
  --spacing-12: 48px;
  --spacing-16: 64px;
}
:root {
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;
  --space-12: 48px;
  --space-16: 64px;
}

.card {
  padding: var(--space-6);
  gap: var(--space-2);
}

Sizing utilities like w-64 and size-10 read the same namespace, so the reset removes them too, and arbitrary values like gap-[13px] still compile. If that is too strict for your codebase, keep the defaults and treat 1, 2, 3, 4, 6, 8, 12 and 16 as the only numbers you type. The scale decides which values exist. Whitespace decides where the big ones go.

Resources

Search concepts

Search for a command to run...