はじめに
こんにちは。レコチョクの河野です。プロダクトデザイナーとして、EggsやGIGGSのプロダクト開発とデザインシステム構築を担当しています。
これまでデザインシステムについての知見や実践例は、記事や社外勉強会の場でも発信してきました。
こういった発信してきた一方で、最近社内の各チームからデザインシステムに関する問い合わせや相談を受ける機会が増えてきました。そこで、あらためて社内向けにデザインシステムに関する勉強会を企画し、その中でEggsやGIGGSで実践してきた構築方法やFigma運用のノウハウを共有しました。当日はSlackの実況チャンネルでリアルタイムにコメントや質問が飛び交う場となり、それらも踏まえて解説を進めることができました。
この記事では、当日の参加者からのコメントなども含め、勉強会で話した内容のうちデザイントークンにフォーカスして書き起こします。命名管理・OOUIについては命名管理・OOUI編、Figma運用TipsについてはFigma運用Tips編でそれぞれ紹介していますので、あわせてご覧ください。
前提:Saunaというデザインシステム
EggsとGIGGSのUIは「Sauna」という名前のデザインシステムを構築して組み立てています。

Saunaではミッションに「あらゆる階層のデザインが”ととのう”ための仕組みをそろえる」を掲げています。ビジョンとして「関わる人のあらゆる迷いを減らす」を目標にしています。これまでの取り組みの中でデザイントークン、コンポーネントライブラリ、ペルソナシートなどを整備してきました。

勉強会の内容を精査していく過程で、これまでのデザインシステムの取り組みがすべて「単語を統一する」という目的のもとに行われていたことに気づきました。トークンの命名も、画面やコンポーネントの名前のルール化も、突き詰めればチームの中で同じものを同じ言葉で呼べるようにする活動です。
デザインシステムの究極の目的は、チームで使われる単語を統一すること。
この気づきを起点に、今回の勉強会ではさまざまなアプローチからこのメッセージが伝わるように構成しました。デザイントークン、命名管理、Figma運用のどのパートを切り取っても、根底にあるのは「単語の統一」です。
単語が統一されれば、関わる人の迷いが減り、コラボレーションがうまくいくようになります。そのコラボレーションの相手が人であっても、AIであっても、同じ原理が通用します。AIが登場したからといって特別なことをする必要はありません。もともと大事なことを丁寧にやれば、AIともアウトプットを最大化できる。そういう考え方でAIが台頭してくる前から、そして今もデザインシステムに取り組んできました。
勉強会の実況用Slackチャンネルでは、開始早々に「DDDとかで出てくるユビキタス言語と同じ考え方ですね」というコメントが飛んできました。ドメイン駆動設計におけるユビキタス言語と本質的には同じ発想です。今回の勉強会でも「ドメイン」という概念が後半で登場するので、エンジニアの方にはとりわけ馴染みやすい内容だったのではないでしょうか。
デザイントークンとは
デザイントークンとは、デザイン要素にトークン(呼び名)を付与して管理する手法です。

ここではColorトークンを例に説明します。例えばゴミ箱のアイコンを赤く塗りたい場合、トークンが存在しない状況では「#FA4549で塗ってください」と直接色コードで指定することになります。一方トークンを導入した場合は、まずこのUIが「破壊的な操作(destructive)」であるという文脈を分類します。そしてその意味に対応するColorトークンとして Apple/500 などを割り当てます。
こうして2段階で名前をつけてデザイン要素を管理する構造が、デザイントークンの基本的な考え方です。
- 意味的なレイヤー:UI上の文脈に対して付与するトークン。
- 例)
Semantic/Action/destructive
- 例)
- リファレンスレイヤー(参照レイヤー):デザイン要素の値に直接つける名前。
- 例)
Apple/500→#FA4549
- 例)
トークンがないと何が起きるか
トークンがない状態で「このゴミ箱を赤くしたい」と伝えようとすると、いくつもの解釈の揺れが生まれます。

- 「赤くする」のは注意喚起なのか、目立たせたいだけなのか、目的の解釈がバラバラになる。
- 赤色にすると決めても、グラデーションの中のどの赤を使うか人によってバラバラになる。
- 「もうちょっと明るめにしよう」のニュアンスが人によってバラバラになる。
このように単語が統一されていないことで、コミュニケーションの解像度が下がり、結果として成果物にブレが生じます。
Saunaで管理しているデザイントークン

Saunaでは大きく4種類のデザイントークンを定義しています。
| トークンの種類 | 管理しているもの |
|---|---|
| Color | UIの配色全般 |
| Typography | タイポグラフィに関するデザイン要素(font family, weight, size, line height など) |
| Dimension | スペーシング、UIパーツのサイズ(幅・高さ) |
| Opacity | 透明度 |
これらすべてにおいて、参照レイヤーと意味的なレイヤーの2階層で設計しています。設計する際に押さえるべきポイントを端的にまとめると、次の2点です。

- 参照レイヤーでは、調和したスケールを定義すること
- 意味的なレイヤーでは、UIに現れる「文脈」を「観察して」分類するところからスタートすること
ここから、Color・Typography・Dimensionそれぞれの設計について詳しく説明していきます。
Colorトークンの設計
参照レイヤーの設計
Colorの参照レイヤーは、いわゆるカラーパレットです。ゼロから手作業で作るのではなく、GitHubが公開しているデザインシステムのカラージェネレーター「Primer Prism」などを活用して生成しました。

HSLの色空間上で、0から9の10段階で明度が段階的に下がっていくようなパレットを構築しています。ここでの「調和」とは、単に横方向(同一色相内のグラデーション)が綺麗に繋がっていることだけでなく、縦方向(異なる色相間で同じ明度帯のトーンが揃っている)も含みます。突拍子もなく一色だけ明るかったりすると、実際のUI上で使いづらくなるためです。
Saunaは元々Eggs向けに開発されたデザインシステムです。そのため、黄色系のパレットに Banana という名前をつけ、Banana/500がEggsのブランドカラーと一致するように調整しています。
色は最初から全部用意すべきか?
参加者から「カラーパレットの色の種類は最初からいろいろな色を想定して作成すべき? それとも使いそうな色だけ定義して後から増やしていくのが良い?」という質問がありました。
各社いろんな解決の仕方をしています。HSLの色相を20等分してパレットを最初から全色用意しているところもあるし、色が近すぎると逆に迷うので間伐して、必要なタイミングで追加する会社もあります。Saunaでは機械的に全色展開する方法も検討しましたが、結局迷いが生まれると判断し、まずは必要な色だけ定義しておいて、必要になったタイミングで追加するという戦略を採用しました。
10段階もスケールを展開しているのは、コントラスト比の担保などで微調整を行えるようにするためです。同じ色で塗っても、アイコンと文字では明るさの見え方が異なるため、隣のスケールにずらして微調整するという運用をしています。基準は500番に揃え、細かいチューニングで300番や600番を使うといった具合です。
意味的なレイヤーの設計
参照レイヤーのパレットをもとに、UIの文脈ごとにトークンを定義していきます。 あらかじめ、UI上での文脈を分類した上で、それらにパレット上での色を割り当てていくイメージです。

例えば Text/Neutral には白色系のStone、Ranking/Up には緑系のForest、Ranking/Stay にはグレー系のStoneを割り当てます。FigmaのDev Modeを開いたとき、開発者はカラーコードを意識せずとも「ランキング上昇時の色は Ranking/Up だ」と判断できます。
EggsからGIGGSへの改善
EggsでColorの意味的なトークンを設計した際に、1つ問題にぶつかりました。当初 Action と IconStatus という2つの文脈を並列に定義していましたが、アクションができるアイコンはどちらに該当するのか判断がつかなくなったのです。

問題の本質は、Action がユーザーが行う動作の文脈、IconStatus が色を塗る対象物を表しており、次元の異なるものを同じ階層に並べてしまったことにありました。
Eggsよりも後発で開発を進めたGIGGSではこの反省を踏まえ、意味的なレイヤーのトークンの分類を文脈(共通/アクション/インタラクション/インフォメーション等)で統一しました。加えて、FigmaのVariablesのScope機能を活用して、各トークンがどのプロパティ(背景/テキスト/ボーダーなど)に適用されるかを制御する設計に改良しています。

これによって文脈とフィル対象を分離して管理できるようになりました。同一の文脈の中で異なる対象物を塗る場合でも、トークンの選択に迷うことがなくなりました。
Typographyトークンの設計
Typographyのトークン設計で扱う要素は、Font Size(フォントサイズ)だけではありません。Font Family(フォントファミリー/書体)、Weight(ウェイト/太さ)、Line Height(ラインハイト/行間)など、テキスト表現を構成する複数の要素があります。Saunaではこれらをデザイントークンとして定義しています。どの要素も最終的なUIの印象に影響するため、いずれも重要です。

ここでは便宜上、フォントサイズを例にとって参照レイヤーの設計プロセスを説明していきます。
参照レイヤーの設計
モバイルアプリのUIでは、小さいサイズは細かく調整できるようにしたい一方、大きいサイズは大胆に選択肢を絞って調和を保ちたいという要求があります。これを実現するために、Saunaでは調和数列を使ってフォントサイズのスケールを設計しました。
ベースのフォントサイズを16とし、調和数列の係数をそれぞれに掛けて、小さい方と大きい方のサイズを算出します。できあがるスケールは次のとおりです。
11 → 13 → 14 → 16 → 18 → 21 → 26 → 32 → 43 → 64

調和数列を使うと、一番大きいサイズが全角1文字分、その次が全角2文字分でぴったり収まるという視覚的な美しさも得られます。これは経験的に知られている性質で、多くのプロダクトが調和数列ベースのスケール設計を採用している理由の1つです。GMOペパボのデザインシステムではHarmonic Typographic Scale Calculatorが公開されています。こうしたツールの存在によって、手軽に調和数列を活用したフォントサイズ設計ができることも大きなメリットです。
意味的なレイヤーの設計
Typographyの意味的なレイヤーでは、Material Design 3の分類を参考にテキストの用途を5種類に分類しています。
| 分類 | 用途 |
|---|---|
| Display | 最も注目させたい要素 |
| Headline | セクションの見出し |
| Title | リストなどで並列表示する要素の名前 |
| Body | 記事本文など、長く読ませるテキスト |
| Label | 注釈やサブ情報 |
それぞれの分類に対して、Font Sizeの展開(Large / Medium / Small)を設定します。さらに必要に応じてLine Heightの展開(広め / 普通 / 狭め)を組み合わせてスタイルを定義するのが基本的な考え方です。
Eggsでの実例
具体的なEggsの実例として、デザインリニューアル時におけるTypographyトークン設計は、UIの全画面を印刷して1つずつ観察するというプロセスから始まりました。

約60画面分のUIを紙に出力し、それぞれのテキスト要素がDisplay / Headline / Title / Body / Labelのどれに当てはまるかをポストイットで分類していきます。単に「観察」といってもUIを眺めるだけではなく、一般論で言われている5分類がEggsにも通用するのかを検証するという目的意識を持って取り組みました。

観察の結果、大半は5分類でカバーできました。一方、判断に迷う箇所も多数出てきます。それらは「揺らぎの記録」として丁寧に残しておきます。

Eggsの場合、特にボタンのテキストだけはどの分類にもうまくハマらないことが判明しました。そこでEggsでは6つ目の分類としてButtonを新設しています。こうした揺らぎのデータが、Button分類の新設や各分類のサイズ展開の粒度を決める際の判断材料になりました。

分類が確定したら、Excelでフォントサイズ・ウェイト・ラインハイトを微調整しながら、各スタイルの具体的な値を詰めていきます。「Headlineは基準サイズより大きくしたいが18だとでかすぎるので16のままウェイトで差をつけよう」といった検討を繰り返し、最終的なスタイル定義に落とし込んでいきました。

Dimensionトークンの設計
参照レイヤーの設計
EggsとGIGGSでは、デザイン要素のサイズ(widthやheight)は基本的に偶数で統一するというルールを設定しています。 UI上で使用できる4の倍数を参照レイヤーとして定義し、UI要素のサイズや要素間のスペースなどの意味的なレイヤーがそれらの数値を参照できるような設計にします。
意味的なレイヤーの設計(例:スペーシング)
ここでは、Dimensionトークンの中でも特にスペーシング(間隔)のトークン設計を例として説明します。
スペーシングのスケール設計にはフィボナッチ数列を採用しました。基準サイズを8として、次に16を設定します。フィボナッチ数列の性質(前の2項を足したものが次の項になる)に従い、8 + 16 = 24、16 + 24 = 40 というスケールを展開しています。Eggsではさらに1段階小さいXSを追加し、GIGGSでは入力画面など細かい要素への対応のためにXXSも追加しました。
(XXS) → XS → S:8 → M:16 → L:24 → XL:40
従来よく言われていた4刻みや8刻みのスペーシング設計では、「近いサイズのスペーシングがバラバラに使われて統一感がない」という問題が起きがちでした。フィボナッチ数列ベースのスケールであれば、小さいところでは微調整しやすく、大きいところでは選択肢が絞られるため、迷いなく使えます。
実際にエンジニアから「スペーシングのトークンが一番役に立った」と好評でした。これまでデザイナーが何となく数値で指定していたスペースも、「ここはM」「セクション間はXL」と明確に伝えられるようになったためです。
また、デザイナー側も「もう1サイズ広げたい」と感じた時にLからXLへとトークンを切り替えるだけで済むので、細かな数値調整に頭を悩ませる必要がなくなりました。
コードビルドシステム
Figma → JSON → 定数ファイル
Figmaの中でいくら綺麗にトークンが定義されていても、それを手打ちで実装コードに反映しているとミスが発生します。そのため、Figmaで定義されたトークンを自動的に実装で使用可能なコード(定数定義)に変換する仕組みを整備することが非常に効果的です。 Saunaでは、FigmaのVariablesからJSONファイルを書き出しています。そのJSONを各プラットフォームの定数ファイル(.swift / .kt / .dart)に変換するスクリプトを構築しました。

ここで重要なのは、実装に使用する言語やフレームワークによって定数ファイルの形式が大きく異なるということです。そのため、この仕組みの構築にはデザイナーだけで閉じず、実装担当のエンジニアを早めに巻き込むことを強くお勧めします。
Eggsでも最初のスクリプトは自分が書きましたが、その後のメンテナンスは実装担当のエンジニアに委ねています。これは意図的に責務を分けた判断で、「1人がリードすべきだが、1人で完成させる必要はない」というデザインシステム構築のスタンスを体現しています。
最近のアップデート
この領域では2つの大きな動きがありました。
1つ目はFigma Dev Mode MCPの登場です。AIにFigmaのデザインデータを読み取らせて実装コードを生成するフローが現実的になってきました。自前で変換の仕組みを作り込まなくても、AIに任せるという選択肢が生まれています。
2つ目はW3CによるDesign Token Format Modulesの標準化です。これまでトークンの定義を出力したJSONの形式はツールや人によってバラバラでした。W3CのCommunity Groupによってツール間の受け渡しをスムーズにするための標準仕様の策定が進んでいます。今後コードビルドシステムの設計やJSONの管理方法を考える際には、この動きを意識しておくとよいでしょう。
まとめ
デザイントークンの構築で大事なのは、「観察」から始めて、調和したスケールを設計し、UIの文脈を丁寧に分類していくことです。
初めてデザイントークンに取り組む場合は、全領域を一度にカバーしようとする必要はありません。チームが一番困っているところから小さく始めるのが成功のコツです。EggsやGIGGSでも、最初から全部できていたわけではありません。
最後に、このセクションに関連する参考資料を紹介します。
参考資料
河野穣
2019年新卒のエンジニアです.iOS修行中.