デザイントークンとは
実際のCSS設計で、一番最初に記述するのがデザイントークンです(以下トークン)。
トークンとは、語源的に「しるし・証」を意味し、数値や色そのものではなく、
余白・文字サイズ・色などの役割を名前で表した最小単位。
変数と異なり、デザインのルールを共有・再利用するための仕組み。
トークンの実態
トークンの実態はただのCSS変数であるが、名前で役割を定義し、
値には実際に使われる具体的な数値を入れる。
:root {
--color-text: #111;
--space-2: 1rem;
--fs-2: 1.25rem;
}
トークンは2種類
①プリミティブトークン
- 生の値を名前付きで定義した最下層のデザイントークン。
- 色・サイズ・数値そのものを直接表す
- bg用、text用などの、用途は記述禁止
- 直接UI設計では使わず、センマティックを経由することが主
- 命名は カテゴリ + 段階 のみ
:root {
/* color primitives */
--gray-0: #ffffff;
--gray-900: #111111;
--gray-500: #3b82f6;
/* size primitives */
--size-1: 0.25rem;
--size-2: 0.5rem;
--size-3: 1rem;
/* radius primitives */
--radius-sm: 4px;
--radius-md: 8px;
}
②センマティックトークン
いわゆる意味トークン。
「何のために使う値か」を表す。
ここから先は主にセンマティックトークンの説明となる。
トークン名の決め方
見た目や実際の数値ではなく、役割で名前をつける。
基本フォーマット
プリミティブ : --カテゴリ-段階
センマティック: --カテゴリ-役割
カテゴリ
まず、カテゴリを先頭に書く。(省略可)
| カテゴリ | 例 |
|---|---|
| 色 | color |
| 余白 | space |
| 文字・文字サイズ | font・fs |
| 角丸 | radius |
--space-*
--color-*
--fs-*
役割
どこで/何に使うかを記述する。
--color-bg /* バックグラウンド*/
--color-panel /* カード背景など */
--color-text /* 本文 */
--color-muted /* 補足 */
--color-border /* 境界線 */
--space-section /* セクション間 */
--space-content /* 要素間 */
段階
3〜5段階くらいがちょうどいい。
--space-1
--space-2
--space-3
--space-sm
--space-md
--space-lg
基本的な記述
まずセレクタに:rootを指定し、
その中でCSS変数を記述していく。
:root {
--fs-1: ;
--fs-2: ;
--fs-3: ;
}
トークン内で記述すること
※意味トークンに生の値を記述することも可。
【必須】 余白 / 色 / フォントサイズ
このまま初期テンプレとしてもOK
:root {
/* 余白 */
--s-1: 0.5rem;
--s-2: 1rem;
--s-3: 1.5rem;
/* 色 */
--color-text: #111;
--color-bg: #fff;
--color-muted: #666;
--color-border: #ddd;
/* フォントサイズ */
--fs-1: 1rem;
--fs-2: 1.25rem;
--fs-3: 2rem;
}
【その他】
角丸
:root {
--r-1: 8px;
--r-2: 16px;
--radius-sm: var(--r-1);
--radius-md: var(--r-2);
}
レイアウト・コンテナ幅
コンポーネントのmax-width等に代入される。
:root{
--container: 64rem; /* 1024px相当 */
}
フォント初期設定
サイト全体で使う標準フォント(デフォルトフォント)を定義するトークン。
OS・ブラウザ・言語環境によって利用できるフォントが異なるため、
左から順に使用可能なフォントが適用される仕組みになっている。
:root{
--ff-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
"Hiragino Kaku Gothic ProN", "Noto Sans JP", "Yu Gothic", sans-serif;
}
その他にも
シャドウ、行間系など、
必要に応じて書き足していく。
判断基準
- 2回以上出る
- 数値に意味がある
- 人によって判断がブレそう
- 変えたら全体に影響する
→ 全部トークン化候補
プリミティブトークン 値の決め方
迷ったらとりあえずこれ入れとけ
:root {
/* Color */
--gray-0: #ffffff;
--gray-50: #f7f7f7;
--gray-100: #eeeeee;
--gray-300: #cccccc;
--gray-500: #888888;
--gray-700: #444444;
--gray-900: #111111;
/* Space */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 1rem; /* 16px */
--space-4: 1.5rem; /* 24px */
--space-5: 2rem; /* 32px */
/* Font size */
--fs-1: 0.875rem; /* 14px */
--fs-2: 1rem; /* 16px */
--fs-3: 1.25rem; /* 20px */
--fs-4: 1.5rem; /* 24px */
--fs-5: 2rem; /* 32px */
/* Radius */
--radius-1: 4px;
--radius-2: 8px;
--radius-3: 12px;
}
色 / 余白 / 文字サイズ / 角丸があればまず困らない
数は少なめ、後で増やす前提
迷ったら 8pxスケール + rem に寄せる
fluid
※編集中
デザイントークンテンプレ
基本的には、先に意味トークンを記述してから
必要な分だけプリミティブトークンを指定することが多い。
チャッピー作。
/* =========================================
Design Tokens (Definitive)
Semantic -> Primitive
========================================= */
:root {
/* -----------------------------------------
1) Typography (Semantic)
----------------------------------------- */
/* Font families */
--ff-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
"Hiragino Kaku Gothic ProN", "Noto Sans JP", "Yu Gothic", sans-serif;
--ff-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace;
/* Font sizes (fluid recommended) */
--fs-xs: clamp(0.8125rem, 0.78rem + 0.15vw, 0.875rem); /* 13-14 */
--fs-sm: clamp(0.9375rem, 0.90rem + 0.20vw, 1rem); /* 15-16 */
--fs-md: clamp(1rem, 0.96rem + 0.25vw, 1.125rem); /* 16-18 */
--fs-lg: clamp(1.25rem, 1.10rem + 0.60vw, 1.5rem); /* 20-24 */
--fs-xl: clamp(1.75rem, 1.45rem + 1.20vw, 2.25rem); /* 28-36 */
/* Line heights */
--lh-tight: 1.2;
--lh-normal: 1.6;
--lh-loose: 1.8;
/* Letter spacing */
--ls-tight: -0.02em;
--ls-normal: 0;
/* -----------------------------------------
2) Spacing (Semantic)
----------------------------------------- */
--space-xs: var(--space-2);
--space-sm: var(--space-3);
--space-md: var(--space-4);
--space-lg: var(--space-5);
--space-xl: var(--space-6);
/* UI用途の意味 */
--space-content: var(--space-md); /* 要素間(カード内など) */
--space-section: clamp(3rem, 2.2rem + 2vw, 6rem); /* セクション間 */
/* -----------------------------------------
3) Color (Semantic)
----------------------------------------- */
--color-bg: var(--gray-0);
--color-panel: var(--gray-50);
--color-text: var(--gray-900);
--color-muted: var(--gray-600);
--color-border: color-mix(in srgb, var(--color-text) 12%, transparent);
/* Accent / State */
--color-primary: var(--blue-600);
--color-primary-weak: color-mix(in srgb, var(--color-primary) 18%, transparent);
--color-success: var(--green-600);
--color-warning: var(--amber-600);
--color-danger: var(--red-600);
/* Link */
--color-link: var(--color-primary);
--color-link-hover: color-mix(in srgb, var(--color-primary) 78%, var(--color-text));
/* Focus ring */
--color-focus: color-mix(in srgb, var(--color-primary) 55%, transparent);
/* -----------------------------------------
4) Radius / Border (Semantic)
----------------------------------------- */
--radius-sm: var(--radius-2);
--radius-md: var(--radius-3);
--radius-lg: var(--radius-5);
--border-1: 1px;
/* -----------------------------------------
5) Shadow (Semantic)
----------------------------------------- */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08);
--shadow-md: 0 8px 24px rgba(0, 0, 0, 0.12);
--shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.16);
/* -----------------------------------------
6) Motion (Semantic)
----------------------------------------- */
--dur-fast: 120ms;
--dur-normal: 240ms;
--dur-slow: 360ms;
--ease-standard: cubic-bezier(.2, .0, .2, 1);
--ease-emphasis: cubic-bezier(.4, 0, .2, 1);
/* -----------------------------------------
7) Layout / Z-index (Semantic)
----------------------------------------- */
--container-sm: 48rem;
--container-md: 64rem;
--container-lg: 80rem;
--header-height: 64px;
--tap-size: 44px;
--z-base: 0;
--z-header: 10;
--z-overlay: 100;
--z-modal: 1000;
/* -----------------------------------------
8) Component-ish (Optional Semantic)
----------------------------------------- */
--btn-height: 40px;
--btn-radius: var(--radius-md);
--card-radius: var(--radius-lg);
--card-padding: var(--space-lg);
}
/* -----------------------------------------
Theme Override (Dark)
- semanticだけ上書きでOK
----------------------------------------- */
:root[data-theme="dark"] {
--color-bg: var(--gray-950);
--color-panel: var(--gray-900);
--color-text: var(--gray-50);
--color-muted: var(--gray-400);
--color-border: color-mix(in srgb, var(--color-text) 14%, transparent);
--color-primary: var(--blue-400);
--color-primary-weak: color-mix(in srgb, var(--color-primary) 22%, transparent);
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
--shadow-md: 0 10px 30px rgba(0, 0, 0, 0.45);
--shadow-lg: 0 18px 60px rgba(0, 0, 0, 0.55);
}
/* =========================================
Primitives (Raw values)
- 迷ったら8pxスケール + rem
- 必要になったら増やす
========================================= */
:root {
/* Grays */
--gray-0: #ffffff;
--gray-50: #f7f7f7;
--gray-100: #eeeeee;
--gray-200: #e6e6e6;
--gray-300: #d1d1d1;
--gray-400: #a3a3a3;
--gray-500: #7a7a7a;
--gray-600: #5a5a5a;
--gray-700: #3f3f3f;
--gray-800: #2a2a2a;
--gray-900: #141414;
--gray-950: #0b0b0b;
/* Accents */
--blue-400: #60a5fa;
--blue-600: #2563eb;
--green-600: #16a34a;
--amber-600: #d97706;
--red-600: #dc2626;
/* Space (8px-ish scale in rem) */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 1rem; /* 16px */
--space-4: 1.5rem; /* 24px */
--space-5: 2rem; /* 32px */
--space-6: 3rem; /* 48px */
/* Radius */
--radius-1: 2px;
--radius-2: 6px;
--radius-3: 10px;
--radius-4: 14px;
--radius-5: 18px;
}