ほとんどのUIを立て直す、余白をめぐる5つの決断
インターフェースがどこか噛み合わないのに、その理由を言葉にできない。そんなときの原因は、たいてい余白にあります。パレットでもタイプフェイスでもなく、その「間」です。余白とは、何がひとまとまりで、何が別物で、何が最も重要なのかを目に伝える、目に見えないシステムです。しかもその崩れは静かに進みます。13pxの間隔を警告してくれるlinterは標準では存在せず、「リズムが壊れている」とレビューに書く人もいません。自分のインターフェースも他人のインターフェースも何年も監査してきましたが、私が加える余白の修正はほぼすべて、同じ5つの決断のいずれかに収まります。 {.answer-block}
TL;DR
- スケールを決め、そこから外れた値をすべて拒否する。 4、8、16、24、32、48、64。13pxの間隔はデザインの決断ではなく、ただのドリフトです。
- グループ間の余白は、グループ内の余白より大きくする。 このゲシュタルトの原則ひとつで、罫線やボックスの大半は不要になります。
- すべてのコンテナに、役割から導いたpaddingを1つだけ与える(コンポーネントは16、カードは24、セクションは32-48)。辺ごとに目分量で調整してはいけません。
- 区切り線に手を伸ばす前に、余白に階層をつくらせる。 罫線とは、余白があきらめた姿です。
- 垂直リズムはテキストのレベルで整える。 line-heightは最低1.5、見出しの後ろの余白は前の余白より小さく。ここが崩れていると、上位のどんな調整でもページは救えません。
1. スケールを決め、そこから外れた値を拒否する
どの値を選ぶかは、最初の決断のうち小さいほうの半分にすぎません。大きいほうの半分は、値の集合が存在すると合意することです。私の場合は4px基準で、4、8、16、24、32、48、64の7つ。それぞれにトークンを1つずつ割り当てます。(データテーブルやツールバーのような密度の高い面では、12が正当化されることもあります。必要ならトークンにしてください。罪なのは名前のない値であって、8つ目のトークンではありません。)
| トークン | 値 | 用途 |
|---|---|---|
| xs | 4px | インライン要素、アイコンまわりの間隔 |
| sm | 8px | グループ内の関連する要素 |
| md | 16px | 標準的なコンポーネントのpadding |
| lg | 24px | カードのpadding、セクション内の間隔 |
| xl | 32px | 主要なセクションの分離 |
| 2xl | 48px | セクションの最大値、ページレベルの最小値 |
| 3xl | 64px | ヒーローセクション |
具体的な数値そのものより、拒否する姿勢のほうが重要です。恣意的な値(13px、7px、22px)はリズムを壊し、目はそれを「雑さ」として感じ取りながらも、正体を言葉にできません。私が自分に課しているルールはこうです。余白の値はすべてスケールから取るか、文書化された理由を伴うか、そのどちらかである。実際には、文書化された例外がレビューを生き延びることはほとんどありません。「そのときはそれが正しく見えた」という感覚こそ、スケールが防ごうとしているドリフトそのものだからです。
スケールは決断の数も圧縮します。スケールがなければ、あらゆる間隔が実装の速度で下される新しい判断になります。スケールがあれば、ほとんどの間隔には妥当なトークンがちょうど1つしか存在せず、デザインレビューは算術ではなく本当に面白いケースを議論できるようになります。
2. グループ間の余白 > グループ内の余白
この記事から1文だけ持ち帰るなら、これです。グループ間の間隔は、グループ内の間隔より目に見えて大きくなければならない。 これは、ゲシュタルトの「近接」が構造を支える仕事をしている状態です。目は相対的な距離を関係性として読み取ります。自動的に、そして言葉より先に。
ラベルとフィールドの距離が8px、フィールド同士の距離が24pxのフォームには、ボックスも区切り線も背景の色付けも要りません。グループが自明だからです。この距離を一律16pxに均してしまうと、同じフォームが等間隔の行の霞になり、ユーザーは意識的に読み解かなければならなくなります。同じ3つのフィールドを、2通りで並べてみます。
grouped (8 within / 24 between) flattened (16 everywhere)
Name Name
[______________]
[______________]
Email Email
[______________]
[______________]
Phone Phone
[______________]
[______________]
左では、それぞれのラベルが自分のフィールドのラベルであることに疑いの余地がありません。右では、内側のラベルが2つのフィールドからちょうど等距離に浮いています。近接が投票をやめてしまい、読み手は見た目ではなく読む順序から所属を割り出すことになります。
失敗の典型は、ほとんど常に「間違ったレベルでの圧縮」です。ファーストビューに詰め込むためにデザイナーがグループ間の間隔を詰め、比率が崩れる。そしてグループがほどけていく感覚を覚え、それを取り戻すために罫線を足す。ここで決断4につながるのですが、その前にもう1つ。
3. コンテナごとにpaddingは1つ、役割から導く
コンテナは、台所にがらくた入れの引き出しが増えていくのと同じように、非対称なpaddingを溜め込みます。ボタンを収めるためにここを少し、アイコンのためにあそこを少し。気づけばカードの上は18px、左は14pxになっていて、理由を覚えている人は誰もいません。解決策は、常に同じ導き方をすることです。コンテナのpaddingは、中身ではなく役割から決まります。
- コンポーネント(ボタン、入力欄、チップ):16px
- カードとグループ化されたコンテンツ:24px
- セクション:32-48px
- ページレベルとヒーロー領域:48-64px
コンテンツが役割のpaddingに収まらないときは、そのコンテナに対してコンテンツのほうが間違っています。分割するか、短くするか、コンテナを1段階上へ昇格させてください。収まりの悪い子要素を1つ救うためにpaddingを調整すれば、兄弟要素すべてのリズムが壊れます。その非対称さは、決して口に出さないユーザーにも「バグ」として映るのです。
4. 罫線より先に余白を
区切り線の大半は言い訳です。リストの行ごとの下線、フォームのセクションごとの囲み、カードとカードの間のヘアライン。そのどれもが、あきらめた余白の姿です。境界線がグループをつくるのは確かです(ゲシュタルトの「共通領域」の原則は本物です)。ただしそれは強い薬でもあります。視覚的に騒がしく、加算的で、積み重なっていく。罫線が1本増えるたびに、目が処理しなければならない線が1本増えます。
私の手順はこうです。まず近接の比率を試す(決断2)。それでもグループが分離しないなら、線を引く前に背景の変化を試す。淡い色面は線を足さずに領域をつくれます。これは「共通領域」によるグループ化の最も静かな形であり、まとまりは必要だが縁は不要というグループには、罫線より必ず優れています。テーブルのゼブラストライプは、この原則の最も見慣れた姿でしょう。罫線に手を伸ばすのは、領域に本当に硬い縁が必要なとき——テーブル、編集可能な領域、入れ子のカードなど——に限り、使うと決めたら一貫して使い切ってください。ここは余白でグループ化し、あそこは罫線でグループ化するインターフェースは、2つのデザインシステムが争っているように見えます。
レビューで私が使うテストはこうです。認められた硬い縁——テーブルや編集可能なフィールド——を示していない罫線をすべて削除し、残ったものを見る。生き残ったグループ化は本物です。ほどけてしまったものは、罫線が肩代わりしていた余白の負債です。
5. 垂直リズムはテキストのレベルで整える
余白のシステムは下から死んでいきます。本文のline-heightが1.2なら、セクションの余白をいくら取ってもページは救えません。段落そのものが窮屈に読め、その上に積み上げたすべてが緊張を受け継ぎます。最低ラインはこうです。本文16px、line-heightは1.5(長文なら1.75まで)、1行の長さは65ch前後。 このうち経験的な裏づけがあるのはline-heightの部分です。アクセシビリティのガイダンスが1.5を挙げているのには理由があり、詰まった行送りはWebで最もよく見かけるリズムの殺し屋です。65chという上限は法則ではなく実践知です。長い行も単体では問題なくテストを通ることがありますが、次の行頭へ目を戻す動きの着地が難しくなり、読み手は論旨に出会うずっと前に「文字の壁」に出会ってしまいます。
段落より上のレベルで、ほかのすべてを組織するルールがこれです。見出しは、その前にある内容よりも、これから導く内容の近くに置く。 見出しの前の余白を後ろより大きく、おおむね2倍が目安です。セクションの間に等距離で浮かぶ見出しは、どちらのものでもありません。その非対称さこそが、見出しを自分の内容に結びつけます。同じ見出しを、2通りで並べてみます。
bound (before wide / after tight) floating (equal both sides)
...end of previous section. ...end of previous section.
Shipping address Shipping address
[Street___________]
[City_____________]
[Street___________]
[City_____________]
左では、見出しが自分のフィールドを所有していることが見て取れます。右では見出しがセクションの間を漂い、読み手は見た目ではなく慣習によって所属を割り当てます。これは決断2が、今度は文字組みのカラムの内側で働いているだけです。そこが要点です。垂直リズムは別の分野ではなく、近接のルールを最小のスケールで適用したものにすぎません。
監査
5つの決断は、どの画面にも当てられるレビュー用のチェックリストに圧縮できます。
- すべての間隔がスケール上にありますか。(外れている値は調べてください。必ず事故です。)
- グループ間の間隔は、そのグループ内の間隔より大きいですか。
- 各コンテナは、役割から導いたpaddingを1つだけ持っていますか。
- 背後の余白を直せば削除できる罫線はありませんか。
- 文字組みのカラムは自前のリズムを保っていますか。line-heightは1.5以上で、見出しは自分の内容に結びついていますか。
たいていの画面は、このうち2つか3つで落ちます。そしてそこを直したときの印象の変化は、パレットやタイプフェイスの入れ替えよりも大きいのです。私自身のiOSアプリでは、1番目の問いを機械的に強制しています。コミットが出ていく前に、レビューのゲートが差分から生のpadding値をgrepし、キットのトークンでない値は、生き残るために名前のある理由を必要とします。余白は職人技が隠れる場所です。誰も指差せないからこそ、そうなのです。
よくある質問
デザインシステムにはどの余白スケールを使うべきですか
4px基準のスケール——4、8、16、24、32、48、64——で、インターフェースに必要なほぼすべての間隔をまかなえます。正確な値そのものより重要なのは排他性です。すべての間隔はスケールから取るか、文書化された根拠を持つか、どちらかにしてください。恣意的な値(7px、13px、22px)は視覚的なリズムを壊し、ユーザーはそれを感じ取りながらも名前を付けられません。
罫線を使わずにUI要素をグループ化するには
近接の比率を使います。グループ間の余白は、グループ内の余白より目に見えて大きくしてください。ラベルとフィールドの間が8px、次のラベルまでが24pxあれば、ボックスを1つも使わずにフォームをグループ化できます。罫線は硬い縁が本当に必要な領域——テーブルや編集可能な領域——に取っておき、その手前の段階として背景の変化を優先しましょう。
カードやボタンのpaddingはどのくらいにすべきですか
コンテナの役割から導いてください。コンポーネント(ボタン、入力欄)は約16px、カードは24px、セクションは32-48px、ヒーロー領域はそれ以上です。コンテナごとに値は1つ。役割のpaddingにコンテンツが収まらないなら、辺を手作業で微調整するのではなく、コンテンツを変えるかコンテナを昇格させてください。
タイポグラフィにおける垂直リズムとは何ですか
テキストのカラムを下へたどるときの、一貫した余白のパターンのことです。本文は最低16px、line-heightは1.5から1.75、1行あたり65文字前後、そして見出しは、その前にある内容よりも、これから導く内容の近くに置きます。これより上のすべては、このレベルから受け継ぎます。段落が窮屈なら、セクションの余白ではページは直りません。