くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

デザイントークンとはなにか、仕様ドラフトをみてみた

デザイントークン、便利そうだけど、よくわからなかったので、
いろいろ調べてみたときの備忘録(*´ω`*)

雑多なまとめ

  • デザイントークンは、デザインを構成する最小要素(トークン)を定義した シンプルなkey-valueペアやkey-valueペアのまとまり
  • デザインと実装の連携をスムーズにするだけでなく、組織の共通言語になる (redといえば#F44336、狭い余白といえば2pxなど)
  • デザイントークンにもいくつか種類がある
  • 仕様はDesign Tokens Community Groupが策定中(2023年6月現在)
  • 仕様策定中なので、現在は各ツール固有の仕様になっている

Design Tokens Community Group

デザイントークンについては、W3Cのコミュニティグループの
Design Tokens Community Groupで議論されているよう。

デザイントークンとは

GitHubのREADMEに書いてある説明としては、こんな感じ。

Design tokens are indivisible pieces of a design system such as colors, spacing, typography scale.

デザイントークンは、色、間隔、タイポグラフィ スケールなどのデザイン システムの分割できない部分です。

パーサーの字句解析や自然言語解析などのトークンと同じ意味合いのよう。

字句解析はそれを、言語的に意味のある最小単位トークンに分解する処理である。

デザイントークンに関連する用語

仕様ドラフトの用語の章がわかりやすい。ここを起点に。

ファイル形式関連

  • ファイル形式: JSON
  • ファイル拡張子: .tokens or .tokens.json
  • MIME type: application/design-tokens+json

JSON Shemaもこのグループが作成してくれる予定っぽい。

The group is currently exploring the addition of a JSON Schema to support the spec.

ツール関連

Design tool

デザインを作成/編集するツール

Bitmap画像

Photoshop / Affinity Photo / Paint.net

Vector画像

Illustrator / Inkscape

UIデザイン

Adobe XD / UXPin / Sketch / Figma

Translation tool

デザイントークンをjson/yaml/xml/cssなどに変換するツール

Theo / Style Dictionary / Diez / Specify

Documentation tool

デザイントークンの使い方を文書化するためのツール

Storybook / Zeroheight / Backlight / Specify / Supernova / Knapsack


デザイントークンの定義関連

ここからが本題。

(Design) Token

名前がつけられた情報。ミニマムなname/valueペア。

{
  "token-name": {        // Name
    "$value": "#fff000", // Value
    "$type": "color"     // Type
  }
}
--token-name: #fff000;

(Design) Token Properties

デザイントークンに関連付けられた情報。 例えば、Value/Type/Descriptionなど

Type

(Design) Token Propertiesの一つ。事前に定義されたトークンの種類。
例えば、Color/Size(Dimension)/Durationなど。

ドキュメントにあるのは、
Color/Dimension/FontFamily/FontWeight/Durasion/CubicBezier/Number

また事前定義にはないがFont style/Percentage(ratio)/File(assets)なども。

Description

(Design) Token Propertiesの一つ。トークンの説明するプレーンテキスト。

{
  "Button background": {
    "$value": "#777777",
    "$type": "color",
    "$description": "The background color for buttons in their normal state."
  }
}

Group

特定のカテゴリに属するトークンのまとまり。
例えば、Brand/Alert/Layoutなど

※タイプや目的を推測するために仕様すべきではない

{
  "brand": {            // Group
    "color": {          // Groupのネスト
      "$type": "color",
      "acid green": {
        "$value": "#00ff66"
      },
      "hot pink": {
        "$value": "#dd22cc"
      }
    },
    "typeface": {       // Groupのネスト
      "$type": "fontFamily",
      "primary": {
        "$value": "Comic Sans MS"
      },
      "secondary": {
        "$value": "Times New Roman"
      }
    }
  }
}

Alias (Reference)

別のトークンへの参照。同じ値を複数の名前で扱える

{
  "alias-name": {
    "$value": "{group-name.token-name}" // alias
  },
  "group-name": {
    "token-name": {       // このトークンを参照
      "$value": 1234,
      "$type": "number"
    }
  }
}
--group-name_token-name: 1234;
--alias-name: var(--group-name_token-name);

Composite (Design) Token

複数のname/valueペアをもつ情報。
shadow(color/offsetX...)/typography(color/size...)など、 複数の値が必要なときに使う。

{
  "shadow-token": {
    "$type": "shadow",
    "$value": {
      "color": "#00000080",
      "offsetX": "0.5rem",
      "offsetY": "0.5rem",
      "blur": "1.5rem",
      "spread": "0rem"
    }
  }
}
{
  "space": {
    "small": {
      "$type": "dimension",
      "$value": "0.5rem"
    }
  },

  "color": {
    "shadow-050": {
      "$type": "color",
      "$value": "#00000080"
    }
  },

  "shadow": {
    "medium": {
      "$type": "shadow",
      "$description": "A composite token where some sub-values are references to tokens that have the correct type and others are explicit values",
      "$value": {
        "color": "{color.shadow-050}",
        "offsetX": "{space.small}",
        "offsetY": "{space.small}",
        "blur": "1.5rem",
        "spread": "0rem"
      }
    }
  },

  "component": {
    "card": {
      "box-shadow": {
        "$description": "This token is an alias for the composite token {shadow.medium}",
        "$value": "{shadow.medium}"
      }
    }
  }
}

ドキュメントにあるのは、
Stroke/Border/Transition/Shadow/Gradient/Typography

それぞれ、$typeで指定されたときに必要な/取りうるkey-valueが決められている。


Translation toolでの仕様など

仕様がドラフトなので、各ツールでの仕様や考え方など、違っているっぽい。
標準化された後に、対応されていくIssueなどもあるので、今後はより便利になりそう。

現行では、Style DictionaryのみFlutterに対応しているけど、
そのかわり、StyleGuide的なHTMLはStorybookを使わないといけないっぽい。 Theo/Diezは、Flutter未対応だが、StyleGuideがあるよう。

Theo

# buttons.yml
props:
  button_background:
    value: "{!primary_color}"
aliases:
  primary_color:
    value: "#0070d2"
global:
  type: color
  category: buttons

Style Dictionary

{
  "color": {
    "base": {
      "gray": {
        "light" : { "value": "#CCCCCC" },
        "medium": { "value": "#999999" },
        "dark"  : { "value": "#111111" }
      },
      "red": { "value": "#FF0000" },
      "green": { "value": "#00FF00" }
    }
  }
}

CTI(Category / Type / Item)という考え方/階層化手法はおもしろい

Diez

  • Diez
  • ファイル形式はTypeScript。本体はTypeScript
  • フォーマットはcss系/js系/iOSAndroid/DesignGuide
//colors.ts
import {Color} from '@diez/prefabs';

export const rawColors = {
  tiger: Color.rgba(241, 93, 74, 1),
  marigold: Color.rgba(255, 172, 57, 1),
  clover: Color.rgba(163, 206, 50, 1),
  cyan: Color.rgba(4, 182, 203, 1),
};

export const semanticColors = {
  foreground: rawColors.tiger,
  foreground50: rawColors.tiger.lighten(.5),
  background: rawColors.clover,
  background50: rawColors.clover.lighten(.5),
}

とりあえず、以上!! なんとなくわかってきた気がする。。(*´ω`*)

参考にしたサイトさま