デザイントークン
値に名前を付けるのは、あとで1か所だけ直せるようにするためです。名前は見た目ではなく、役割で付けます。
図の中身を文字で読む
- 何をトークンにするか
- 色 余白 級数 角丸 影 動きの時間
- Aa Aa Aa
- 命名は「順序を固定する」ことが要点
- --color-bg-danger-hover
- color bg danger hover 順序が固定されていれば、アルファベット順に並べたとき
- カテゴリ 対象 役割 状態 関連するトークンが隣り合う。検索もできる。
- ✕ --blue-600 見た目で命名すると、テーマを変えたとき名前と実物が矛盾する ○ --color-text-muted
- ✕ --clr-txt-mtd 省略すると書く手間は減るが、読めなくなる 初めて見た人でも用途が推測できる
ひと目で#
- デザイントークン
- 値に名前を付けて、その名前で参照する仕組み
- プリミティブ
- 値そのものに付けた名前(
--gray-500)。参照してよいのは次の層だけ - セマンティック
- 役割に付けた名前(
--color-text-muted)。部品はここだけを見る - コンポーネントトークン
- 部品固有の名前(
--button-bg)。部品ごとの例外を許す層 - テーマ切り替え
- 役割名はそのまま、定義側の値を差し替える
何をトークンにするか#
色、余白、級数、角丸、影、動きの時間。1か所でしか使わない値と、内容に固有の寸法はトークンにしません。
使い分け#
図の中身を文字で読む
- 参照は一方向。部品はセマンティックだけを見る
- 1. プリミティブ 値の名前 2. セマンティック 役割の名前 3. コンポーネント 部品の例外の口
- --amber-500: 参照 --color-accent: 参照 --button-bg:
- oklch(58% 0.12 68) var(--amber-500) var(--color-accent)
- ✕ 部品からプリミティブへ飛び越えて参照しない。テーマの差し替えが効かなくなる
- 暗い表示ではセマンティックの定義だけを差し替える
- --color-text: var(--gray-900);
- @media (prefers-color-scheme: dark) { --color-text: oklch(94% 0.008 68); }
- 部品側の CSS は1行も触らない。名前が役割のままなので、参照する側は自動で追従する。
| こういうとき | 参照する層 |
|---|---|
| 部品から色を使う | セマンティック(--color-accent) |
| セマンティックを定義する | プリミティブ(--amber-500) |
| この部品だけ色を変えたい | コンポーネントトークンを挟む |
| ダークモードに対応する | セマンティックの定義だけを差し替える |
| 部品の数が少ない | 3層目は省いてよい |
間違えやすいところ#
- 部品からプリミティブを直接参照するテーマの切り替えができなくなる
- 見た目で名付ける(
--blue-600)テーマを変えたとき、名前と実物が食い違う - 省略形を使う(
--clr-txt-mtd)書く手間は減るが、読めない - 命名の順序をばらつかせる
--text-color-mutedと--color-border-subtleが混ざると検索できない - すべてをトークンにする名前が増えすぎて、どれを使えばよいか分からなくなる
- 段を細かく刻む50刻みで19段のグレーを作ると、選べなくなる
実装#
このコードで動いている見本です
上のコードは、琥珀色1色を3層で通した完成例です。--amber-500 が値の名前、--color-accent-text が役割の名前、--button-bg が部品の口。面に敷いて白い文字を載せるので、図形用の --color-accent(3:1)ではなく文字用のほう(白文字で 5.64:1)を使います。暗い表示で差し替えているのは真ん中の層だけで、.button--primary の行は書き換えていません。基底の .button は出発点のCSSに1か所だけ置き、ここでは触りません。1色でこの形になれば、残りの色も余白も同じ形に並びます。
名前を決める#
名前で迷うのは、たいてい系統の切り替わり目です。色・余白・文字・動きの4系統で、判断の基準は同じ1つになります。
| 系統 | ✕ 値や見た目で名付ける | ○ 役割か段で名付ける |
|---|---|---|
| 色 | --blue-600 | --color-text-link |
| 余白 | --gap-big | --space-6 |
| 文字 | --font-14 | --text-sm |
| 動き | --anim-time-2 | --dur-fast |
語順も全トークンでそろえます。--color-bg-danger-hover なら、カテゴリ・対象・役割・状態の順。先頭を固定しておけば、並べ替えたとき関連するトークンが隣り合い、検索でも漏れません。
対の実例と、実物のシステムでの見比べ方を命名の実例集にまとめています。決めた名前を貼れる状態にしたものが出発点のCSSで、案件ごとに差し替えるのは色相・余白の刻み・文字の段の3つだけです。
直す例#
架空の案件を1つ例にとります。どこを見て、何をどう直すかを書きます。
例として、引き継いだ会社案内のサイトに、暗い表示への対応を頼まれました。CSS を検索すると、青系の色コードが 41 か所に直書きされています。しかも近い色が3つ混ざっていて、どれが同じ役割のつもりだったのかは、書いた本人にしか分かりません。この状態から「地の色だけ差し替える」ことはできません。
まず数えます。grep -oE "#[0-9a-fA-F]{3,6}" style.css | sort | uniq -c | sort -rn を通すと、使用回数の多い順に並びます。上位から順に、その色がどの場面で使われているかを見て、役割の名前を与えます。本文なら --color-text、補足なら --color-text-muted、罫線なら --color-border。3つ混ざっていた青は、リンクと見出しと罫線に散っていたので、2つの役割にまとめて1つは捨てました。
置き換えの向きは一方向です。部品は var(--color-text) だけを見る。その --color-text が何色かは、:root の1か所で決める。ここまで済めば、暗い表示の対応は @media (prefers-color-scheme: dark) の中でセマンティックの定義を書き直すだけになり、部品側の CSS には触りません。
名前の付け方に迷ったら命名の実例集に、色・余白・文字・動きの4系統の対があります。決めた名前をそのまま貼れる形にしたものが出発点のCSSです。
コピーする#
部品の側は、こう書けていれば直書きは残っていません。値は :root に集め、部品は役割名だけを参照します。
このコードで動いている見本です
移し終えたか確かめるのは、この1行です。部品のファイルから色コードと固定の px が消えていれば、テーマの差し替えが1か所で効きます。
grep -nE "#[0-9a-fA-F]{3,6}|[0-9]+px" css/components/*.css
確認する#
- 部品の CSS を色コードで検索して、1件も出てこない
- 暗い表示へ切り替えるとき、部品側の CSS を1行も触っていない
- 新しく足した名前が、既存の階段(
--space-1〜--space-10)で代用できないと言える
使えるパターン#
このページで扱う語#
このページで扱う語を並べる本文では太字4 語
語の名前から引くなら用語索引へ。
- プリミティブトークン
- 値そのものに名前を付けた最下層のトークン。役割ではなく、何色か何ピクセルかを表す。
- セマンティックトークン
- 役割で命名し、プリミティブトークンを参照する中間層のトークン。
- トークン命名
- トークンにどう名前を付けるかの規約。階層・対象・強さ・状態を一定の順序で並べる。
- カスタムプロパティ
- CSS 内で値に名前を付けて再利用できる仕組み。`--name` の形で定義する。
この話が要る場面#
このページが答えになる、現場の困り事です。困り事の側から探すと、同じ場所に着きます。
値に名前を付けて共有する。色・余白・角丸・影・時間をトークンにする。
このコードで動いている見本です
値ではなく役割で付ける。--space-3 のような段階名か、--color-text-muted のような用途名。
このコードで動いている見本です
同じトークンを両方から参照する。図面と実装で別々に値を持たない。
このコードで動いている見本です
この場面のほかの困り事と、そのまま貼れる部品は同じものを同じに作るにまとめてある。逆引きには全188件。
作業台で決める#
この値は作業台で決められます。和文の予約ページに載せて、幅と明暗を替えて確かめてから CSS を持ち帰る: 部品がトークンに追従する