デザイントークンの3層アーキテクチャとは何か、単一層のトークン命名方式とどう違うのか?
単一層の命名法は最も初期的で直感的な方法だ——色や数値を直接説明的に命名する、例えばblue-500で特定の青色の色番号を表す。この命名法はトークン数が少ないうちは非常に使いやすいが、デザインシステムが拡大するにつれて問題が表面化する——あるボタンの背景色にblue-500が使われており、後で「すべてのプライマリボタンの背景色」を別の色に統一したいと思っても、blue-500がボタンとは全く無関係な十数箇所(リンクテキスト、アイコンの色、ボーダー)でも同時に使われていることが判明し、1つの値を変更することで影響を受けるべきではない広範囲の場所まで連動してしまう。
3層アーキテクチャはこの問題を解決するため、命名を3つの独立した階層に分割する。第一層「グローバル原始値」(Global/Primitive)は原始的な数値そのものを定義することだけを担当する、例えばblue-500 = #2D5BD6で、用途には一切関与しない。第二層「セマンティックエイリアス」(Semantic/Alias)はこの原始値に用途志向の名前を与える、例えばcolor-action-primaryがblue-500を指す。この層は「この色がどのような状況で使われるか」に答える。第三層「コンポーネント専用」(Component-specific)は特定のコンポーネントがセマンティック層のトークンを参照する、例えばbutton-primary-backgroundがcolor-action-primaryを指す。色を変更する際は第二層の対応関係を調整するだけでよく、下層の原始値に触れる必要もコンポーネント層を一つずつ変更する必要もない。
なぜ3層アーキテクチャが発展する必要があったのか、それはどのような背景の問題を解決するのか?
このアーキテクチャの出現は、デザインシステムが規模化した後に必然的に発生する「トークンの混乱」問題に直接対応している。デザインシステムに数十個のトークンしかない場合、単一層の命名で十分だ——人間がどのトークンがどこで使われているかを覚えていられるからだ。しかしトークン数が数百から千を超えて成長し、複数のプラットフォーム(ウェブ、iOS、Android)と複数のテーマ(ライト、ダーク、ブランドバリエーション)をカバーするようになると、単一層の命名法は「このトークンを安全に変更できるかどうか」をコードベース全体を検索しなければ答えられない問題にしてしまい、デザインと開発のイテレーション速度を大幅に遅らせる。
3層アーキテクチャの核心的な考え方は、「原始値が何であるか」と「この値がどのような用途を表すか」を、独立して変更できる2つの関心事に分割することだ——原始値は安定を保てる(特定の青色のカラーコードは頻繁には変わらない)が、セマンティック層の対応関係はブランドの調整やダークモードの切り替えに応じて変化しうる。コンポーネント層はほとんど変更の必要がなく、セマンティック層を安定的に参照するだけだからだ。この階層化により、「色の変更」「ダークモードの切り替え」「ブランドアイデンティティの調整」といった一般的な大規模変更が、コードベース全体を一つずつ確認する必要なく、中間層を調整するだけで済むようになる。
3層アーキテクチャは具体的にどのように機能するのか、各層間の参照関係はどうなっているのか?
具体的な参照チェーンは一方向だ——コンポーネント層のトークンはセマンティック層のトークンを参照し、セマンティック層のトークンはグローバル層のトークンを参照し、グローバル層のトークンはそれ自体が終点であり、他のトークンを参照しない。具体的な例で説明する:グローバル層はgray-900 = #1A1A1A(純粋な色の値)を定義する。セマンティック層はcolor-text-primary = {gray-900}を定義する(この色に「主要テキストカラー」という用途を与える)。コンポーネント層はheading-text-color = {color-text-primary}を定義する(見出しコンポーネントがこのセマンティックな用途を参照する)。後でダークモードを調整する必要がある場合、セマンティック層がダークモード下で異なるグローバル値を指すようにするだけでよい(例えばcolor-text-primaryをダークモードではgray-900ではなくgray-100を指すように変更する)。コンポーネント層は全く変更の必要がない——具体的な色の値ではなく、セマンティック層という安定した中間的な名前を参照しているからだ。
実際の導入では、ツール(Style Dictionaryなどのトークン変換ツール)を使ってこの3層の定義を構造化されたファイル(通常はJSONまたはYAML)として記述し、各プラットフォームが読み取れる形式(CSS変数、iOSの.swift定数、AndroidのXMLリソース)を自動生成することが一般的だ。これにより、デザイナーがFigmaでセマンティック層の対応関係を調整すると、全プラットフォームのコード変更を直接同期させることができ、エンジニアが一つずつ手動で修正する必要がなくなる。
読者やデザインシステムを構築中のチームにとって実際にどのような影響があるのか?
あなたのチームがゼロからデザイントークンを構築しているなら、3層アーキテクチャは初日から採用する価値がある——トークン数が膨張して保守困難になってから後でリファクタリングするのではなく。すでに多数のコンポーネントから直接参照されているフラットな命名システムをリファクタリングするコストは、最初から階層化して設計するコストよりはるかに高い。具体的な着手方法:まずチームが本当に必要とする「セマンティックな用途」(プライマリアクションカラー、セカンダリテキストカラー、危険警告カラーなど)を列挙し、それからその用途を支えるグローバル原始値を定義する——先に色の値を山ほど定義してから、後でどう分類すべきか考えるのではなく。
あなたのチームが既にフラット命名のトークンシステムを持ち、3層アーキテクチャへのリファクタリングを検討しているなら、実際のコスト効果の判断ポイントは次の通りだ——チームが今後半年から1年の間に、大量のコンポーネントにまたがる変更(大規模な色のリブランディング、ダークモードの追加、マルチブランド対応など)を必要とすると予想しているかどうか。そうした需要が発生しないなら、現状を維持する方がリファクタリングのエンジニアリングコストより割に合うかもしれない。そうした需要が確実に発生するなら、早くリファクタリングするほど、その後の大規模な変更ごとのコストは低くなる。
Material Design 3(Googleのデザインシステム)が採用するトークンアーキテクチャは、まさにグローバル(Reference Tokens)、システムセマンティック(System Tokens)、コンポーネント(Component Tokens)の3層分業の実例である——システムセマンティック層はprimaryやon-primaryといった用途志向のロールを定義し、ダークモード切り替え時はシステム層が指す参照値を調整するだけでよく、これらのロールを使用する数千のコンポーネントは個別に修正する必要が全くない。
3層アーキテクチャの利点は、大規模な変更(色の変更、ダークモードの切り替え、マルチブランド対応)が中間のセマンティック層を調整するだけで済み、保守と追跡のコストを大幅に削減できることだ。欠点は、初期構築に追加の思考と計画の時間が必要であること(セマンティックな用途分類を事前に明確に定義する必要がある)、そしてトークン数が少なくチームが小規模なプロジェクトにとっては、このアーキテクチャがもたらす初期の複雑さが、実際に解決する問題の規模を超えてしまう可能性があることだ。