色コードの直書き、フォントサイズのハードコーディング、余白の値がファイルごとにバラバラ ── UIの規模が大きくなるほど、こうしたスタイルの不整合は深刻な負債になります。デザイントークンは、この問題を「名前付きの値」で解決する仕組みです。

デザイントークンの定義

デザイントークンとは、色・フォント・余白・角丸・シャドウといったUI上の視覚的属性を、プラットフォームに依存しない形式で記述した「名前と値のペア」です。CSS変数やSassの変数と似ていますが、単なるコード上の定数ではなく、デザインツール・Web・iOS・Androidなど複数環境で共有できる点が異なります。

たとえば「ブランドカラーの青」を #0066CC というHEX値で覚えるのではなく、color.brand.primary という名前で管理します。値を変更する場合は1箇所を更新するだけで、全プラットフォームに反映されます。

変数との違い

CSS変数(--color-primary: #0066CC;)やSass変数($color-primary: #0066CC;)は特定の言語に紐づいています。デザイントークンはJSON形式で定義し、ビルドツールを通じてCSS・Swift・Kotlin・XMLなど任意の言語・フォーマットに変換できます。

{
  "color": {
    "brand": {
      "primary": {
        "$value": "#0066CC",
        "$type": "color",
        "$description": "ブランドのメインカラー"
      }
    }
  }
}

上記はW3C Design Tokens Community Group(DTCG)が策定中のDesign Tokens Format Moduleに準拠した記法です。$valueで値を、$typeで型を、$descriptionで説明を記述します。

トークンの3階層構造

デザイントークンは通常、3つの抽象度に分けて管理します。用語は組織によって異なりますが、概念は共通しています。

第1層: グローバルトークン(プリミティブ)

カラーパレットやフォントスケールなど、抽象度が最も低い「生の値」を格納する層です。コンテキストを持たず、値そのものを定義します。

{
  "color": {
    "blue": {
      "50":  { "$value": "#E3F2FD", "$type": "color" },
      "100": { "$value": "#BBDEFB", "$type": "color" },
      "500": { "$value": "#2196F3", "$type": "color" },
      "700": { "$value": "#1976D2", "$type": "color" },
      "900": { "$value": "#0D47A1", "$type": "color" }
    },
    "gray": {
      "100": { "$value": "#F5F5F5", "$type": "color" },
      "300": { "$value": "#E0E0E0", "$type": "color" },
      "700": { "$value": "#616161", "$type": "color" },
      "900": { "$value": "#212121", "$type": "color" }
    }
  },
  "font": {
    "size": {
      "xs":  { "$value": "12px", "$type": "dimension" },
      "sm":  { "$value": "14px", "$type": "dimension" },
      "md":  { "$value": "16px", "$type": "dimension" },
      "lg":  { "$value": "20px", "$type": "dimension" },
      "xl":  { "$value": "24px", "$type": "dimension" },
      "2xl": { "$value": "32px", "$type": "dimension" }
    }
  }
}

第2層: セマンティックトークン(用途別)

グローバルトークンを参照しながら、「何に使うか」という意味を付与する層です。エイリアス(別名参照)の仕組みで上の層とつなぎます。

{
  "color": {
    "text": {
      "default":  { "$value": "{color.gray.900}", "$type": "color" },
      "subtle":   { "$value": "{color.gray.700}", "$type": "color" },
      "inverse":  { "$value": "#FFFFFF",           "$type": "color" }
    },
    "bg": {
      "surface":  { "$value": "#FFFFFF",           "$type": "color" },
      "muted":    { "$value": "{color.gray.100}",  "$type": "color" },
      "accent":   { "$value": "{color.blue.500}",  "$type": "color" }
    },
    "border": {
      "default":  { "$value": "{color.gray.300}",  "$type": "color" },
      "focus":    { "$value": "{color.blue.700}",  "$type": "color" }
    }
  },
  "font": {
    "size": {
      "body":    { "$value": "{font.size.md}", "$type": "dimension" },
      "heading": { "$value": "{font.size.xl}", "$type": "dimension" },
      "caption": { "$value": "{font.size.xs}", "$type": "dimension" }
    }
  }
}

{color.gray.900} のように波括弧で囲んだ表記がエイリアス参照です。DTCG仕様では、この参照構文によってトークン間の依存関係を宣言的に表現できます。

第3層: コンポーネントトークン(部品固有)

特定のUIコンポーネントに紐づく値を定義する層です。ボタン・カード・フォーム入力など、部品ごとのスタイルをセマンティックトークンから組み立てます。

{
  "button": {
    "primary": {
      "bg":           { "$value": "{color.bg.accent}",    "$type": "color" },
      "text":         { "$value": "{color.text.inverse}",  "$type": "color" },
      "border-radius": { "$value": "8px",                  "$type": "dimension" },
      "padding-x":    { "$value": "16px",                  "$type": "dimension" },
      "padding-y":    { "$value": "8px",                   "$type": "dimension" }
    }
  },
  "input": {
    "border":       { "$value": "{color.border.default}", "$type": "color" },
    "border-focus": { "$value": "{color.border.focus}",   "$type": "color" },
    "bg":           { "$value": "{color.bg.surface}",     "$type": "color" },
    "font-size":    { "$value": "{font.size.body}",       "$type": "dimension" }
  }
}

この3層構造の利点は、変更の影響範囲を制御できる点にあります。たとえばブランドカラーを変更する場合、第1層の color.blue.500 を書き換えるだけで、第2層の color.bg.accent と第3層の button.primary.bg に自動的に伝搬します。

別称役割変更頻度
グローバルプリミティブ / リファレンス生の値を定義低い(リブランディング時)
セマンティックエイリアス / システム用途に意味を付与中程度(テーマ追加時)
コンポーネント固有 / スペシフィック部品ごとのスタイル高い(UI改善時)

DTCG仕様が定義するトークンの型

W3C Design Tokens Community Groupが策定中の仕様では、トークンに設定できる型($type)が定められています。主な型は以下の通りです。

基本型:

型名用途値の例
color#FF5733, rgb(255, 87, 51)
dimensionサイズ・余白16px, 1.5rem
fontFamilyフォントファミリー["Noto Sans JP", "sans-serif"]
fontWeightフォントの太さ400, bold
durationアニメーション時間200ms
cubicBezierイージング関数[0.4, 0, 0.2, 1]
number単位なし数値1.5, 0

複合型(複数の基本型を組み合わせたもの):

型名用途構成要素
shadowボックスシャドウoffsetX, offsetY, blur, spread, color
borderボーダーcolor, width, style
transitionトランジションduration, delay, timingFunction
gradientグラデーション色停止点の配列
typographyタイポグラフィfontFamily, fontSize, fontWeight, lineHeight等

この型情報があることで、ビルドツールが値を適切な形式に変換できます。たとえば color 型のトークンは、CSSでは #FF5733、Swiftでは UIColor(red: 1.0, green: 0.34, blue: 0.2, alpha: 1.0) のように出力を切り替えられます。

Style Dictionaryによるトークンの変換

デザイントークンのJSONファイルを各プラットフォーム向けのコードに変換するには、ビルドツールが必要です。代表的なツールがStyle Dictionaryです。Amazon(現在はオープンソースコミュニティ)が開発しており、Node.js上で動作します。

導入手順

# プロジェクトにインストール
npm install style-dictionary

# 初期設定ファイルを作成
npx style-dictionary init

設定ファイルの例

config.json でトークンのソースと出力先を指定します。

{
  "source": ["tokens/**/*.json"],
  "platforms": {
    "css": {
      "transformGroup": "css",
      "buildPath": "build/css/",
      "files": [
        {
          "destination": "variables.css",
          "format": "css/variables"
        }
      ]
    },
    "ios-swift": {
      "transformGroup": "ios-swift",
      "buildPath": "build/ios/",
      "files": [
        {
          "destination": "StyleDictionary.swift",
          "format": "ios-swift/class.swift",
          "className": "StyleDictionary"
        }
      ]
    },
    "android": {
      "transformGroup": "android",
      "buildPath": "build/android/",
      "files": [
        {
          "destination": "colors.xml",
          "format": "android/colors"
        }
      ]
    }
  }
}

ビルドの実行

npx style-dictionary build

このコマンドを実行すると、tokens/ 以下のJSONファイルから以下の出力が得られます。

CSS出力 (build/css/variables.css):

:root {
  --color-brand-primary: #0066CC;
  --color-text-default: #212121;
  --color-bg-surface: #FFFFFF;
  --font-size-body: 16px;
  --font-size-heading: 24px;
}

Swift出力 (build/ios/StyleDictionary.swift):

public class StyleDictionary {
    public static let colorBrandPrimary = UIColor(red: 0.000, green: 0.400, blue: 0.800, alpha: 1)
    public static let fontSizeBody: CGFloat = 16.00
}

1つのJSON定義からCSS・Swift・Kotlin(Android XML)が同時に生成されるため、デザイナーが値を変更した際にも各プラットフォームの実装を手作業で更新する必要がありません。

Figma Variablesとの連携

Figmaは2023年にVariables機能をリリースし、デザインツール上でもトークンの概念をネイティブに扱えるようになりました。Figma上で定義したVariableは、REST APIやプラグインを通じてJSON形式でエクスポートできます。

連携の流れ

  1. Figmaでの定義: デザイナーがFigma Variables画面でカラー・数値・文字列・ブーリアンの各モードを設定
  2. エクスポート: Tokens Studio for FigmaプラグインまたはFigma REST APIを使い、DTCG互換のJSONとして書き出し
  3. Gitリポジトリで管理: エクスポートしたJSONファイルをGitリポジトリにコミット
  4. ビルドパイプラインで変換: CIでStyle Dictionaryを実行し、CSS/Swift/Kotlinなどへ変換
  5. デプロイ: 変換後のファイルをnpmパッケージやCocoaPods/Maven経由で各プロジェクトに配布

この仕組みにより、Figma上のデザイン変更がコードベースに自動的に反映されるワークフローが構築できます。

トークン命名規則のベストプラクティス

命名規則はチーム全体の可読性とメンテナンス性に直結します。主要なデザインシステムの実装から共通するパターンを整理します。

基本構造

カテゴリ.用途.バリアント.状態
要素説明
カテゴリcolor, font, spacing, shadow値の種類
用途text, bg, border, iconUIのどこに使うか
バリアントprimary, secondary, danger意味的な区分
状態default, hover, disabled, focusインタラクションの状態

命名の指針

  • 抽象的な名前を優先する: color.errorcolor.red-500 より変更に強い
  • 略語を避ける: bg は広く認知されているため許容されますが、btn-pd のような独自略語は避けてください
  • スケールは数値で表現する: font.size.sm / font.size.md / font.size.lg のようにTシャツサイズを使うか、100 / 200 / 300 の数値スケールを使うか、チームで統一します
  • ネストの深さは3〜4階層まで: component.button.primary.hover.bg のように5階層以上になる場合は構造の見直しを検討してください

ダークモード対応とテーミング

デザイントークンの大きな強みの一つが、テーマの切り替えです。セマンティック層のトークンを差し替えるだけでライトモード/ダークモードを実現できます。

ライトモード

{
  "color": {
    "text": { "default": { "$value": "{color.gray.900}" } },
    "bg":   { "surface": { "$value": "#FFFFFF" } }
  }
}

ダークモード

{
  "color": {
    "text": { "default": { "$value": "{color.gray.100}" } },
    "bg":   { "surface": { "$value": "#121212" } }
  }
}

CSS出力では、prefers-color-scheme メディアクエリやクラス名の切り替えで適用します。

:root {
  --color-text-default: #212121;
  --color-bg-surface: #FFFFFF;
}

[data-theme="dark"] {
  --color-text-default: #F5F5F5;
  --color-bg-surface: #121212;
}

グローバルトークン(第1層)はモードによらず共通のまま、セマンティックトークン(第2層)の参照先だけを切り替えるのが設計のポイントです。同じ手法で「ハイコントラストモード」や「ブランドB用テーマ」といった追加テーマも管理できます。

日本国内の導入事例

SmartHR Design System

SmartHRでは、プリミティブトークンとセマンティックトークンの2層構造を採用しています。プリミティブトークンでカラーパレット・タイポグラフィ・スペーシングの基礎値を定義し、セマンティックトークンで「テキスト色」「背景色」「ボーダー色」などUIの用途に紐づけています。非推奨トークンの管理もドキュメント上で明示し、移行ガイドを提供している点が特徴です。

参考: SmartHR Design System - デザイントークン

Serendie Design System(三菱電機)

三菱電機が公開するオープンなデザインシステム「Serendie」では、W3C DTCG仕様に準拠したトークンフォーマットを採用しています。リファレンストークンとシステムトークンの2層に加え、テーマごとの色分けとCompact/Expandedの密度バリエーションを提供しています。FigmaとコードのトークンをGitリポジトリで同期する運用フローも公開されています。

参考: Serendie Design System - デザイントークン

デジタル庁デザインシステム

デジタル庁は行政サービス向けのデザインシステムを公開し、デザイントークンをGitHub上でオープンソースとして管理しています。CSS Custom Propertiesとして提供されており、行政サイト間でUIの一貫性を担保する基盤として機能しています。

参考: デジタル庁デザインシステム - デザイントークン

デザイントークン導入のステップ

既存プロジェクトにデザイントークンを導入する際の手順を整理します。

ステップ1: UIインベントリの作成

現在のプロダクトで使われている色・フォントサイズ・余白・角丸・シャドウの値を洗い出します。CSSファイルからユニークな値を抽出するには、以下のようなコマンドが参考になります。

# プロジェクト内の全CSSから色指定を抽出
grep -rhoP '#[0-9a-fA-F]{3,8}' src/ | sort | uniq -c | sort -rn

類似する値(#333333#333 など)を統合し、実際に必要なパレットを特定します。

ステップ2: グローバルトークンの定義

洗い出した値をカテゴリ別に整理し、JSONファイルとして記述します。まずはカラーとフォントサイズから始めるのが実用的です。

ステップ3: セマンティックトークンの設計

「テキスト色」「背景色」「ボーダー色」「エラー色」など、用途別のトークンを定義します。グローバルトークンへのエイリアス参照で結び付けます。

ステップ4: ビルドパイプラインの構築

Style Dictionaryをプロジェクトに導入し、JSONからCSS変数やSwift定数への変換を自動化します。CIに組み込めば、トークンの変更がPRとして可視化されます。

ステップ5: 既存コードの段階的な置き換え

ハードコードされた値を徐々にトークンの参照に置き換えます。一括置換ではなく、コンポーネント単位で移行するとリスクを抑えられます。

/* Before */
.button {
  background-color: #2196F3;
  color: #FFFFFF;
  padding: 8px 16px;
  border-radius: 8px;
}

/* After */
.button {
  background-color: var(--color-bg-accent);
  color: var(--color-text-inverse);
  padding: var(--button-primary-padding-y) var(--button-primary-padding-x);
  border-radius: var(--button-primary-border-radius);
}

デザイントークンとアトミックデザインの違い

アトミックデザインはUIを「原子 → 分子 → 有機体 → テンプレート → ページ」の5段階で分類するコンポーネント設計の方法論です。一方、デザイントークンはコンポーネントそのものではなく、コンポーネントを構成するスタイル値の管理手法です。

観点デザイントークンアトミックデザイン
対象スタイルの値(色、サイズ、余白)UIの構造(ボタン、カード、ページ)
粒度値単位コンポーネント単位
目的一貫性のあるスタイル管理再利用可能なUI部品の体系化
出力JSON / CSS変数 / Swift定数React Component / Vue Component

両者は競合するものではなく、補完関係にあります。アトミックデザインで設計したコンポーネントの内部スタイルをデザイントークンで管理する、という組み合わせが実践的です。

デザイントークンの起源と標準化の動向

デザイントークンの概念は、2013〜2014年にSalesforceがSalesforce1プラットフォームの開発過程で生み出しました。スタイルガイドの値をOS横断で共有する仕組みとして「デザイントークン」という用語が命名され、後にLightning Design Systemとして公開されています。デザイン属性をJSONで定義し、複数プラットフォームに配信するこのアプローチは、UI開発における大きなパラダイムシフトでした。

その後、W3Cの下にDesign Tokens Community Group(DTCG)が設立され、トークンの記述フォーマットの標準化が進められています。2026年2月時点でDesign Tokens Format Moduleは「Draft Community Group Report」の段階にあり、$value$type$description をはじめとするプロパティの仕様が定義されています。

Design Tokens Format Module - W3C Community Group

Google Material Design 3でもデザイントークンが体系的に採用されており、Material Theme Builderを通じて動的なテーミングを実現しています。

まとめ

デザイントークンは、UIの視覚的属性を「名前付きの値」として一元管理する仕組みです。3階層構造で変更の伝搬を制御し、Style DictionaryのようなビルドツールでCSS・Swift・Kotlinへ自動変換することで、デザインとコードの乖離を防ぎます。

導入の効果は規模が大きいほど顕著になります。複数プラットフォームに展開するプロダクトや、ダークモード対応が必要なサービスでは、トークンによるスタイル管理が開発効率とUI品質の両立に貢献します。

W3C DTCGによる仕様標準化が進み、Figma VariablesやStyle Dictionaryといったツールチェーンも成熟してきた現在は、デザイントークンを導入するのに適した時期です。まずはカラーパレットとフォントサイズの2カテゴリからJSONファイルを作成し、小さく始めてみてください。