見出し画像

デザイントークンの効果的な命名方法

サイボウズでkintoneのデザインシステム開発をしているトビ(@0b1tk)です。こんにちは。
今回はデザイントークン、特にセマンティックトークンの命名方法について掘り下げます。

まずはデザイントークンの定義について、W3Cから設立されたデザイントークンの仕様策定をするコミュニティ「Design Tokens Community Group」の定義を引用いたします。

Design tokens are indivisible pieces of a design system such as colors, spacing, typography scale.
(訳:デザイン・トークンとは、色、スペーシング、タイポグラフィ・スケールなど、デザインシステムを構成する不可分の要素のことである)

Design Tokens Community Group

このデザイントークンの名前づけについて「値的な名前」と「意味的な名前」の2つに分類できます。

  • 値的な名前:Global token(別名 Primitive token, Base token)

  • 意味的な名前:Semantic token(別名 Alias token, Brand token)

この記事では、後者の「意味的な名前」のトークンを「セマンティックトークン」と呼びますが、効果的な命名によってデザインとコーディングの両方において共通理解を飛躍的に向上させることができます。

ここではデザイントークンの整備の経験と知見のもと、FigmaプラグインのTokens Studioを活用したセマンティックトークンの効果的な命名方法についてご紹介します。


なぜセマンティックトークンが必要なのか?

デザイントークンは、デザイナーとエンジニアがそれぞれのプラットフォームで利用できるように、CSS変数(カスタムプロパティ)としてコードベースに反映されます。

つまり、異なるツールを用いる異職種が、同じトークン名という"共通言語"を使用することでコミュニケーションが円滑になります。
共通認識が揃うと開発速度は向上し疑問解消や不必要な説明労力を削減できるだけでなく、疑問解消や不必要な説明労力の削減だけでなく、誤ったトークンを実装してしまう手戻りのリスクも低減するからです。

しかし、安直にトークン名を定義するのは危険です

例えば「blue.50」という値をそのまま使ったトークン名や「oceanBlue」のような概念的なトークン名だと、"どの青色か"を明示していないため利用者ごとに異なる青色を連想する可能性があります。
またトークンの数が膨大になったとき、デザイントークン設計の使用意図や論理的根拠がわからないと、どのトークンが特定のユースケースに適用されるかがうやむやなまま使用される恐れがあります。

デザイナーとエンジニアがGlobal Tokenでやりとりする様子
「$blue.50」から「$color-button-background-normal」と命名すると、
デザイナーの意図を汲んでエンジニアは実装できる。

そのため『真に意味が伝わるトークン名』であるためには、全員が名前を見ただけで『トークンの利用用途』がわかるぐらい明示的なセマンティックトークンを命名する必要があります。

・・・

セマンティックトークンのための命名階層

では、明示性のあるセマンティックトークンの命名階層について詳しく説明します。

私が所属するkintone Design Systemチームでは、デザイントークンの命名方法についてチーム内での共通理解を揃えるため、毎週開催している勉強会で以下の英語記事を題材にしました。

そしてその知識をもとに、Figmaプラグインである「Tokens Studio」を使用するときのセマンティックトークンの命名秩序について議論しました。
思想としてはモジュラーなCSS設計思想であるBEMのシンタックス(Block-Element-Modifier)に近いです。

セマンティックトークンは、次の4つの命名階層から構成されます。

1. カテゴリー階層(Category level) - color / sizing / spacing …
2. オブジェクト階層(Objects level) - group component / component …
3. ベース階層(Base level) - property / concept
4. 修飾子階層(Modifier level) -  variant / state / scale …

4つの命名階層にセマンティックトークンを当て込んだ例

明確な命名階層があることで、デザイントークンを適切に分類できるので、その利用者にとってスケーラブルかつ予測可能なトークンを提供できます。

前置きをすると、デザイントークンの命名方法に厳格な正解はありません。
ここで紹介する命名階層はあくまで一例で、もし既にチーム内で合意の取れたタクソノミーシステム(分類法)があるならば、Category → Objects → Base → Modifierの階層順に従う必要はありません(この4つに階層優位性はありません)。
しかし留意していただきたいのは、あなたが1度決めた命名階層は遵守するべきです。
デザイントークン設計にあたりさまざまな企業事例をリサーチするかと思いますが、無秩序なネーミングをしてしまうと直感性に欠けるだけでなく、使用者によって解釈に齟齬が生じたり、改修が必要な負債リスクが増えます。
デザイントークン設計に携わる人たちのあいだで、やり方や視座が揃っていることが大切です。


1. Category level / カテゴリー階層

カテゴリー階層は、サイズ・スペース・カラーなどのトークンを分類わけする階層です。Tokens StudioにおけるSizing・Spacing・Colorといった左ペインにあるリストタイトルにあたります(※1)

Tokens Studioを起動した画面
└── Category level
    ├── sizing (サイズ)
    ├── spacing (スページング)
    ├── color (カラー)
    ├── box-shadow (シャドー)
    ├── line-height (行間)
    ├── …


(※1)参考記事の”Naming Tokens in Design System”ではCategoryはBase levelの子レイヤーに位置しますが、Tokens Studio Pro機能のAdvanced Theming(高度な分類分け)でNew Setを登録しない限り、出力されるJSONファイルの先頭要素はCategory level(sizingなど)になります。
そのため、命名構成の先頭に切り出しています。

"Naming Tokens in Design System"より


2. Objects level / オブジェクト階層

  • Component(コンポーネント):コンポーネント名

  • Component groups(コンポーネントグループ):コンポーネントが組み合わさっている集合体名

  • Nested Elements(ネストエレメント):コンポーネントに内包された要素名

└── Objects level
    ├── Component (コンポーネント)
    │   └── button, checkbox, dropdown, inputText …
    ├── Component Group (コンポーネントグループ)
    │   └── form, checkboxGroup, radioGroup …
    └── Nested Elements (ネストエレメント)
        └── inputText-left-link, inputText-right-icon …


3. Base level / ベース階層

  • Property(プロパティ):Categoryが示す場所や属性名

  • Concept(コンセプト):グルーピングされた概念名

└── Objects level
    ├── Property(プロパティ)
    │   ├── text, background, border, popup …
    └── Concept(コンセプト)
        └── header, body, footer …


4. Modifier level / 修飾子階層

  • Variant(バリアント):複数のバリエーション示す種類名

  • State(状態):Objectsの状態名

  • Scale(スケール):量・倍率・サイズなどの定量的な指標名

  • Mode(モード):light / darkモードの区別や、ブランドカラーテーマ名(※2)

└── Modifier level
    ├── Variant(バリアント)
    │   ├── primary, secondary, success, error …
    ├── State(状態)
    │   ├── active, disabled, focus, hover …
    ├── Scale(尺度)
    │   ├── 1, 2, 3, s, m , l, 1-x, 2-x …
    └── Mode(モード)
        └── on-light, on-dark …

(※2)lightモードがdefaultなことが多く、セマンティックトークン名が冗長になるのを避けるために、darkモードのみ「on-dark」を付ければいいという考えもあります。
また、on-といった前置詞を入れると読みやすくなる一方、入力コストも考慮してチームの判断に委ねましょう。

"Naming Tokens in Design Systems"より


・・・

セマンティックトークン命名時の注意点

セマンティックなデザイントークンの命名において特に注意すべきポイントやよくある失敗についても補足します。デザイントークンの名前を決めるときは慎重に命名を行うことが必要です。

1. 冗長性の排除

セマンティックトークンにおいて「トークン名はシンプル」かつ「トークン数は最低限」であるべきです。

これまで紹介した命名階層では、Element・Concept・Modeなど使用頻度の低い命名要素が含まれていますが、これらを無理にトークン名に含める必要はありません
なぜならば、トークン名に要素が増えるほど使用可能な範囲が狭まり、ユースケースカバレッジが制限されるからです。つまり、命名に制限をかけるほど将来的な変更や拡張が負担になる可能性が高まります。

ユースケースカバレッジの広さと、トークン名の長さを横軸で表す。
トークン名に要素を盛り込むほど、使用できる箇所(ユースケースカバレッジ)が狭まる。

例えば、「text-color-default」というセマンティックトークンは、テキストのあらゆる場所で幅広いユースケースに適用できる一方で、「text-title-color-default」はテキストの中でもタイトルにしか適用できません。

また、トークン名が長いほど、誤入力や打ち間違いなどのヒューマンエラーも発生しやすくなります。


トークンの数に関しては、同じ値を持つ場合でも、既存の実装に合わせてトークンそのものを不用意に追加するのは避けるべきです。

たとえば、Buttonが { STATE = normal, hover, disabled } という3つの状態を持つとき、これらの各STATEに対するフォントサイズ用のトークンをそれぞれ用意するとしましょう。
すべてのフォントサイズが1remのとき、1.5remに修正が必要になったとすると、各STATEごとにトークンを更新する必要がありメンテナンスコストの増加につながります。

不要な名前要素を削ることで、メンテナンスコストが減る図。

すでにある情報設計を反映させつつ、同じ値を共有できる"共通項"となるトークンがないか観察することで、一貫性を維持しながら余分なトークンの管理や変更の手間を軽減できます。


2. 名前の重複回避

プロダクトサービス内ですでに使われている名称は避けるべきです。

kintoneを例にとると、ユーザーは「アプリ」と呼ばれる交通費申請・顧客対応履歴などの業務システムを自由に作成できるのですが、このアプリは「レコード」という単位でデータを管理しており、それらを構成する1つ1つの項目を「フィールド」と呼びます。

kintoneアプリ内のレコードと、レコード内のフィールド。
kintoneヘルプページより

このとき、もしコンポーネントで"入力可能であること"を示したいがために「Field」という名前をつけてしまうと、人によっては「Fieldという名前から見るに、アプリのレコード内だけでしか使えないコンポーネントなんだ」と誤解を招きかねません。
このような混同を避けるため、名前の重複を避けることで開発者同士のコミュニケーションが円滑に進行します。


3. 利用者全員でつくる

デザイントークンを命名するタイミングが訪れたとき、デザイナーとエンジニアとで一緒に適切な命名を見出すことが重要です

それは「デザインとコードの掛け合わせ」という技術的な相互関係を持つこと以上に、なんのために挑むのかという"原点"に立ち返ってほしいです。
きっとデザイントークン、ひいてはデザインシステムに取り組もうという背景には「プロダクトサービスの一貫性や生産性をよりよくしたい・現状打破したい」という"作り手としての根底の想い"があるはずです。

そして、デザイントークン設計という膨大な工数が求められる作業に、それでもやる価値があると投資価値を見出してくれた組織の期待に応える必要があります。多種多様なデザインを整理し、品質の低下したコードを大規模にリファクタリングする抜本的改革の一環は、むしろチャンスでもあるのです。
この大役を担えるのは、大規模な改革はデザイナーとエンジニアの両者が共通目標に向かうことで成しえます。

より効果的なデザイントークン設計に取り組むときに、この記事を参照しながら討議を進めていただければ幸いです。

・・・

この記事が気に入ったらサポートをしてみませんか?