結論
プロは余白を感覚で置かない。まず「8の倍数(8/16/24/32/48…)」をトークン化して全 padding・margin・gap をそれに吸着させ、細部だけ 4px のハーフステップを許す。その上で「内側の余白 ≤ 外側の余白(internal ≤ external)」を絶対ルールにしてグルーピングを成立させ、上に行くほど刻みが粗くなる非線形スケールで目分量を排除する。「なんとなく」が消えるのは、この3点を仕組みにした時だけだ。
01 — 余白を8の倍数トークンに吸着させる
7px・13px・15px・20px のような任意値を都度入力すると、開発者ですら「13px だったか 14px だったか」を再現できず、全体の整合が崩れて安っぽく見える。dimensions / padding / margin / gap を 8・16・24・32・40・48… に限定し、選択肢を減らすことが一貫性の正体だ。Material / Atlassian / InVision が共通で採る業界標準で、root 16px なら 0.5rem = 8px に一致する。
primarySpacing, grids, and layouts — InVision
primarySpacing methods — Material Design
02 — internal ≤ external でグループを成立させる
「曖昧な余白」は素人っぽさの最大要因だ。グループ内の隙間がグループ間より広いと近接の法則が壊れ、どこからどこまでが1つの塊かが読めなくなる。最も典型的なのが、ラベルが「自分の入力欄」より「上のフィールド」に近いフォーム。ある塊の padding(内側)を、その塊を隣から隔てる margin(外側)以下に保つ——この単一ルールだけで近接が成立する。
blogSpacing best practices — Cieden
blogNotes from 'Refactoring UI' — Gist
03 — 非線形スケール+隣接は最低約25%差
4・8・12・16・…・60・64 のように大きい値まで等間隔で刻むと、16→20px は +25% でも 240→256px は +6.7%。大きい値ほど隣接差が知覚できず、無意味なトークンが量産されて決定疲れを生む。正解は数学的等比ではなく、手で選んだ知覚的に均等な値 = 4/8/12/16/24/32/48/64/96/128px。下は細かく、上は粗く。隣り合う2値は約25%以上離す(近すぎると選べない)。
blogNotes from 'Refactoring UI' — Gist
blogStop Guessing UI Spacing — Lince Mathew
04 — 要素の大小に合わせて余白も変える
見出しも本文も同じ margin、カードもバッジも同じ padding——一律にすると階層が出ない。余白は「関係性」を表すものであり、大きい要素ほど周囲の余白も大きくするのが原則だ。用途別レンジで割り当てる:Small 0–8px=密結合/アイコン↔テキスト、Medium 12–24px=コンテナ内の別要素、Large 32–80px=セクション区切り。関連が近いほど小さく、無関連ほど大きく(Gestalt 近接)。
primarySpacing — Atlassian Design
blogStop Guessing UI Spacing — Lince Mathew
05 — vertical rhythm:line-heightを8(または4)の倍数に固定
font-size はデバイスで 14/15/18/21px と変動してよいが、line-height を 8 の倍数(8/16/24/32、許容で 4 の倍数の 20/24/28)に固定すると、テキストブロックの高さが 8px グリッドに乗り、縦のリズムが揃う。タイポ系と余白系が同じ数列で整合するのがポイント。1.45 のような端数倍率はグリッドから外れ、行ごとに微妙にズレる。
見出し
端数のline-heightで
行が赤グリッドから
少しずつズレる
見出し
line-heightを24pxに
固定すると各行が
グリッド線に乗る
blog8-Point Grid: Typography On The Web — freeCodeCamp
primarySpacing, grids, and layouts — InVision
06 — まず多すぎる余白から入れて削る
Web は構造上どうしても余白不足になりがちだ。詰めた状態から足していくと窮屈なまま固定されてしまう。逆に、最初に過剰なほど余白を入れて満足するまで削る方が、破綻が見えやすく速い。下の例は同じ要素で密度だけを変えたもの——「ケチって始める」より「盛って削る」が正解だ。
blogPrinciples of Design: Negative Space — UX Engineer
実装スニペット
非線形 8px スケールを CSS custom properties で定義する(Refactoring UI 流)。20px や 36px のような中間値はスケールに無い限り使わない。
:root {
/* 下は細かく、上は粗く(隣接 ≥ 約25%差) */
--space-1: 4px; /* 密結合: アイコン↔テキスト */
--space-2: 8px; /* 関連要素・コンポーネント内 */
--space-3: 12px; /* 4px half-step */
--space-4: 16px; /* 標準gap・カードpadding */
--space-6: 24px; /* コンテナ内の別要素 */
--space-8: 32px; /* セクション区切り */
--space-12: 48px; /* ページセクション */
--space-16: 64px; /* heroの余白 */
--space-24: 96px;
--space-32: 128px;
}
internal ≤ external を守ったカード+フォーム。内側 4px < 外側 24px で近接が成立する。
.card {
padding: var(--space-4); /* 内側=16px */
margin-bottom: var(--space-8); /* 外側=32px(内側より大) */
}
/* ラベルは自分の入力欄に近づけ、前のフィールド群から離す */
.field { margin-bottom: var(--space-6); } /* グループ間=24px */
.field label { margin-bottom: var(--space-1); } /* グループ内=4px */
.field input { display: block; width: 100%; }
vertical rhythm:line-height を 8 の倍数に固定し、余白も 8px で刻む。縦 margin は rem、横 padding は px が原則。
body { font-size: 1rem; } /* 16px */
h2 { font-size: 1.5rem; line-height: 32px; margin: 48px 0 16px; }
p { font-size: 1.125rem; line-height: 24px; margin: 0 0 24px; } /* 18/24 */
small{ font-size: 0.875rem; line-height: 20px; } /* 14/20 */
px / rem の使い分け + タッチターゲット最小 48×48px・間隔 8px(Material)。
.btn {
font-size: 1rem; /* rem: 文字拡大に追従 */
min-height: 48px; /* px: タッチターゲット最小 */
padding: 12px 24px; /* 横paddingはpx */
margin-bottom: 1.5rem; /* 縦marginはrem=24px */
border: 1px solid; /* borderはpx */
}
.btn + .btn { margin-left: 8px; } /* 隣接ターゲット間 ≥ 8px */
チェックリスト
- すべての padding / margin / gap が 8 の倍数(8/16/24/32/48…)に乗っているか。細部の調整だけ 4px ハーフステップに留めているか。
- 7px・13px・15px・20px などスケール外の任意値が紛れていないか。
- どの塊も internal ≤ external か(padding ≤ それを隔てる margin)。グループ内 < グループ間になっているか。
- ラベルが「上のフィールド」より「自分の入力欄」に近いか。
- スケールは非線形で、隣り合う2値が約25%以上離れているか。大きい値の等間隔トークンを乱発していないか。
- 大きい要素ほど周囲の余白も大きいか(一律 margin になっていないか)。
- line-height が 8(許容で 4)の倍数で、テキストブロックが縦グリッドに乗っているか。
- font-size と縦 margin は rem、横 padding と border は px にしているか。
- タッチターゲットは最小 48×48px、隣接間 8px 以上あるか。
- 「ケチって始めて」いないか。まず盛って削ったか。
限界 / 出典
secondaryNotes from 'Refactoring UI' — GitHub Gist
blogSpacing best practices — Cieden
primaryOverview - Spacing — Atlassian Design
primarySpacing methods — Material Design
primarySpacing, grids, and layouts — Design Systems by InVision
primaryThe Surprising Truth About Pixels and Accessibility — Josh Comeau
secondary8-Point Grid: Typography On The Web — freeCodeCamp
secondary8-Point Grid — spec.fm
blogBasics: Spacing systems & scales in UI design — Designary
blogStop Guessing UI Spacing — Lince Mathew (Medium)
primaryA new default spacing scale · Tailwind Discussion #12263