新規プロダクトを立ち上げるときに作る、小さなデザインシステム

[Ateam Group Manager ＆ Specialist Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam)の1日目はIncrements株式会社のマネージャー、綿貫が担当します！

## この記事で分かること

- 新規プロダクトのUI作成における下準備の仕方
    - 要件定義や情報設計は既に終わっていて、具体的なUIデータを作る場面が対象
- 1つ1つの要素の意思決定の基準
- 1人のスーパーマンだけで作るのではなく、組織で作る方法

## UIのテーマの決定

ターゲットユーザーやプロダクトの性質からやることやらないことの方向性を考えます。このときインターフェースの見た目はもちろん、トーンオブボイスのような**プロダクトとユーザーのコミュニケーションの仕方**も視野に入れられるとGood。

まとめ方は以下のようなイメージです。

| ターゲットやプロダクトの性質 | やること | やらないこと |
| :-- | :-- | :-- |
| ターゲットの年齢層が高め | 文字やボタンなどのサイズを大きくする | Tinderの左右スワイプのように、新しめの操作のUIを入れる |
| 画面上で複雑な情報や状態が入り乱れる | 情報を「読む」のではなく「見る」ようにまとめる（インフォグラフィック的なアプローチ） | Excelのような見た目でひたすらテキストを羅列する |
| 業務アプリケーション | ビジネスパーソンらしい言葉遣い | Discordのようなフレンドリー過ぎる言葉遣い |

上記はテキストだけで非常に簡単に書いていますが、実際はそれなりに時間をかけます。
見た目のイメージを固めるために画像を持ち寄りムードボードを作ったり、様々な職種混合でサービスを擬人化したイメージを話し合ったり……。

最終的にはいくつかの単語や文章にまで落とし込み、みんなが常に意識しやすいようなテーマとして着地させます。
冗長だったり要素を詰め込み過ぎると役に立ちません。マス向けのキャッチコピーに出来るほど洗練しなくても良いですが、ある程度簡潔な内容にまとめるのは必須でしょう。

---

余談ですが、UIのテーマ決定だからとデザイナーだけで行うのはあまり良くありません。

例えば営業に行くメンバーが「**クライアントに対して○○な訴求が出来ると嬉しい**」「**最新システムではあるけど、対象は昔ながらの業界だからITっぽ過ぎる言葉は伝わらないかもしれない**」といった意見を持っていたとします。

こういった内容はデザイナーの視点からは見えづらい場合も多く、見えていないがゆえに**良かれと思ったのにあまり受け入れられないUI**を生み出してしまいかねません。
全ての意見を反映させるのは無理でも、意見を理解した上で優先度を**みんなで**判断するのは出来ます。

早いうちから色々な立場の人を巻き込んで進めるのは非常にオススメです。

---

## デザイントークンを設定する

上記で決めたテーマを体現出来るように、まずはデザイントークンから設定します。

### カラー

以下に挙げたような種類と役割を考えます。

|種類|内容|
|---|---|
|ベースカラー|白やグレー。背景や重要な要素以外の、画面のほとんどを占める色。|
|メインカラー|頻繁めに使う機能や、結構大事な機能のインターフェースに使う色。|
|アクセントカラー|画面内で最も大事な機能や「ここぞ！」という場所に使う色。|
|テキストカラー|テキスト用の色。ベースカラーと分ける理由は後述。|
|ステートカラー|自分で勝手にそう呼んでいる。色だけでステートを表すべきではないものの、用意しておくと便利な色。|

#### 全ての色に共通

- `Red, Blue, Gray`や`Primary, Secondary, Base`など、命名は様々
    - プロダクト全体で統一さえされていれば、どういったルールで命名しても良いと思う
    - しかし長く運用するプロダクトほど「**後からどうしても追加したくなった色**」が発生しがち
    - そのため、命名には拡張できる余地を残した方が無難に思われる
    - 具体的には
        - 非推奨: Red1, Red2, Red3...
        - 推奨: Red10, Red20, Red30...
        - 2番目の命名であれば、後からどうしても10と20の間のRedが欲しくなってもRed15が作れる
    - 拡張しないのが一番だけど、全部が全部綺麗に回るわけでもないのがデザインデータ

#### メインカラー

- 決めたテーマが楽しい系統の言葉だったら彩度が高い色、などイメージにあう色選びをする
- 白地に対して出来るだけコントラストが4.5:1以上になるようにメインカラーを選ぶ
    - 4.5:1はアクセシビリティの観点
        - 例えば**メインカラーに黄色を選ぶとかなり読みづらい**ため、テキスト要素にはメインカラーが使えない……という事態が起こる
    - [Color.review](https://color.review/)で見るとクリアできるラインが視覚化されていて便利
    - ダークテーマを検討していて、選んだ色が黒地に対してはコントラストが低い場合は下記のどちらか
        - ダークテーマ専用にメインカラーの色合いを調整する
        - 選んだ色を少し調整して黒と組み合わせても4.5:1を達成できるようにする
- 選んだカラーを中心に、明るい色・暗い色を設定する
    - **メインカラーを中心にして、6-10色くらい**用意出来ていれば大抵問題ない
    - [Geenes](https://geenes.app/editor/user-interface)などのサービスを使うと非常に早く作成出来る
        - ただし、生成されたパレットをそのまま使うのは少し危険
        - あくまで計算で生成されているので**見た目に違和感があれば調整した方が良い**
            - そうは言っても1から手動で作ると時間がかかりがち
            - **土台をツールで作成→細部を人力で調整**がバランスが良さそう
- 作ったカラーパレットの各色のコントラスト比を確認する
    - 白地、黒地、白文字、黒文字……と組み合わせた際のコントラスト比をそれぞれ確認
    - どの色はテキスト色や背景色として使えるのか？
    - 逆にどの組み合わせはNGなのか？
    - **コントラスト比3:1ならクリアできる**組み合わせはどれか？
        - 14pt（≒19px）以上の大きな文字なら3:1でもOKとされている
    - 元の色を少し調整すれば都合が良くなる箇所は無いか？
        - 例えば、選んだ色が暗すぎてパレットのうち暗いバリエーションに差をつけられないなど
        - メインカラーを少し明るくしてあげることで**パレット全体が使いやすくなる**パターンもある

#### アクセントカラー

- メインカラーの色相から**120度~180度くらいずらした位置の色**をアクセントカラーとして設定する
    - 厳密に角度が大事というよりは、大きめに色相をずらしておいた方がアクセントとして機能しやすい
- メインカラーで実施したのと同様に明暗のパレットを作成する
- メインカラーで実施したのと同様にコントラスト比の確認する
- メインカラーとアクセントカラーを並べた際の印象を確認する
    - 単体で使う分には良くてもすぐ近くに並ぶとなんだか気持ち悪い……というのは起こり得る
    - どちらか、あるいは両方を調整して、並べて使っても気持ちが良いようにする

#### ベースカラー

- ニュートラルグレーでも良いけど、**グレーに少しだけメインカラーを混ぜたグレースケール**にすると雰囲気が出る
- ベースカラーもメインカラー・アクセントカラーと同様にパレットを作成しコントラスト比をチェックする

#### テキストカラー

- ベースカラーもグレースケールだけど、テキストはテキストで用意した方が良い
    - テキストというオブジェクトは性質上どんな場所にも存在する
    - 不透明度が100%のグレーだと「**メインカラーの上なら良いけどアクセントカラーの上だと読みづらい**」といった事態が起こる
        - Material Designの[Text legibility](https://material.io/design/color/text-legibility.html#legibility-standards)の内容を見ると分かりやすいはず
- 非常に強いこだわりがなければMaterial Designの配色を真似るのがオススメ
    - 読みやすさが確保された組み合わせで、なおかつ管理もしやすい

|テキストの種類|色|
|---|---|
|本文など、重要なテキスト|rgba(0 0 0 / 87%)|
|補足など、やや重要度が下がるテキスト|rgba(0 0 0 / 60%)|
|Disabledなテキスト|rgba(0 0 0 / 38%)|

#### ステートカラー

- alertやwarning、場合によってはsuccessなど、システムの状態を表す色
    - 個人的にこう呼んでいるけど、何か一般的な呼称がある……？
- alertは赤、warningは黄色と、ある程度人間社会に共通した色のイメージがあるのでそれを使う
    - 例えば警告なのにあえて緑をだしても「**っぽく**」見えない
    - メインカラーの彩度が低めだったらステートカラーも彩度を低くするなどの調整はした方がベター
- **ただしあくまで色だけで状態を区別せずに、テキストやアイコンと一緒に使うべき**

### タイポグラフィ

スケールやフォントの種類の話であり、色の話はスコープに入れません。

|種類|内容|
|---|---|
|本文|3-4種類でOK。|
|見出し|作る対象で必要な個数が結構違う。理由は後述|

#### 本文と見出しに共通

- font-familyを決める
    - 和文だけでいくのか、欧文も混ぜるのか
        - OSによってデフォルトで入っているフォントが違うため、和文と欧文で別フォントを指定するなら有り得る組み合わせを確認しておく必要がある
    - Webフォントを使うのか使わないのか
        - 和文Webフォントは2020年の今でもある程度ページスピードが遅くなってしまう
        - 作っているプロダクトの性質や決定したテーマに合わせて選ぶ必要がある
        - いずれにしても「**ブランドが大事だから**」と和文Webフォントを2種類x3ウェイト使用する……みたいなのは絶対やめた方が良い

#### 本文

- 最小サイズを決める
    - **ブラウザで表示できる限界**もあるため、かなり機械的に決められる
    - 年齢層の高いユーザーも多くいるなら最小を13px
        - デザイナーからは「最小が13pxなんてかなり大きいのでは？」と思われそうだけど、年齢が高ければ13pxでも相当小さい部類
    - かなり洗練した印象を出したければ10px
    - どちらでもなければ11pxか12px
- 本文サイズのバリエーションを決める
    - あまりにも種類を増やしても使用シーンに違いが分からなくなるので、**3-4種類で十分**
    - 「本文らしい」見た目にも限界があり、こちらも割と機械的に決められる
        - 要素の少ないサイトであっても**20px**を超えるともう「本文」って印象ではなくなってくる
        - Qiitaのように記事がメインのサイトだと**18px**でも相当な大きさに感じる
    - 等差数列パターン
        - `12, 15, 18`や`11, 13, 15, 17`と**同じ数だけ**増やしていく
    - 等比数列パターン
        - `12, 14.4, 17.28`や`11, 13.75, 17.1875`と**同じ比率を掛けて**大きくしていく
        - 実際は小数点ありの数値としてハードコーディングせず、Sassなどで`$baseSize * 1.2`のように掛ける数値を登録しておく方がベター
    - プライマリーな行間を決めておく
        - 基本的には`line-height: 1.6`で、画面高さに余裕がないときは`line-height: 1.3`も良いとする、などがあり得る
        - フォントサイズが一緒でも行間がバラバラだと印象が変わってしまうので「**特筆すべき理由がなければこの行間**」と決めて置く方が運用しやすい

#### 見出し

- 本文と違い、**プロダクトの属性で考えることが増える**
    - 記事サイトの場合はh1からh6まで使うことも多く、更にリード文などで見出しっぽいサイズがたくさん必要
        - その際それぞれをしっかり区別するために、ジャンプ率も自然と高めになる
    - 業務アプリケーションの場合は情報量が多いなどの制約もあり、そこまでジャンプ率は高くなくて良い
        - 結果的に「見出しの役割」は様々でも「見出しサイズ」はバリエーションが少なくてOKな場合も多い
    - 本文の最大サイズより少し大きいものが見出しでの最小サイズとなる
        - 適切なジャンプ率が出せていないと見出しの最小サイズがうまく決められない
        - 逆に言えば見出しの最小サイズが決まればあとは**必要な個数だけ同じ計算**で増やしていく
        - もちろんここでも見た目の印象で多少調整は入れる
- 本文とは行間や字間を変えた方が良い場合もある
    - 選ぶフォントにもよる
    - フォントサイズが大きいと**視覚的に**行間や字間が広過ぎて見える可能性があるため、見た目の印象でちゃんと調節する
- 見出しサイズはデバイスによって変えた方が良い場合もある
    - 例えば、デスクトップで40pxの見出しは効果的な場面もある
    - しかしモバイルでは相対的に相当大きく表示されるため、長い文章が入るのであれば小さくした方が良いかもしれない

### グリッド

そこまで決めることは多くありません。
端的に言ってしまえば「○pxのグリッドを基準にUIを作ろう」の○の値を考えるだけです。

絶対にコレが良いという値は無いので、チームメンバーが慣れている数値や、他プロダクトからの流用で決めてしまっても良いと思います。
ちなみに私は大抵8pxグリッドで作っています。

ただし細かな調整が発生する場面はあるので例外のガイドラインを定めておくのは必要でしょう。
例えば「**基本8pxの倍数だけど4pxもサブグリッドとして使って良い**」とか「**アイコンとテキストの調整などであれば1pxや2pxを使っても良い**」などが考えられます。
あるいは「**視覚補正の都合で円型を使うときは云々**」「**border-radiusの値のみ別なスケールを用意する**」といった話もあるかもしれませんね。

ガチガチに固めてしまうと大変ですが、ある程度「**拠り所**」になる指針は決めておくと結果的に後から楽に進められます。

---

またもや余談ですが、この記事の中で私は「AもBも考えられるけど、それはどちらでも大丈夫」のような内容を何度か書いています。

これは**チーム内での仕事のやりやすさを阻害してまで適用すべきルールは存在しない**という私の哲学から来ています。

明確なアンチパターンでもなければ、**チームが上手く回りそうなルール**を適用するのが一番。
「まだうちのチームで試したことがないから取り入れてみたい」といった意見があれば、**パッションを尊重して**新しいルールを取り入れてみるのも良いのかもしれません。

この手の話はみんな「**ベストプラクティスが知りたい**」とか「**失敗しないやり方を手に入れたい**」という気持ちになりがちですが、手段が先行してチームの同意を得られないのは非常に不幸です。

あなたのチームではどれが合いそうなのか、を話し合ってみてください。

---

### レイアウト

代表的なレイアウトを先に決めておけるのであれば決めておきます。
例えば下記のような思考でレイアウトのテンプレートを考えられます。

> Master-Detailパターンで、左側にコレクションビューが来て右側にシングルビューが来る。
シングルビューに対してアクションを行うときは右側にもう1ペイン表示される。

このとき、絵として考えるレイアウトとコードとして考えるレイアウトがあります。

例えば全ての幅や高さに`%`や`vw`を使うレイアウトを想定している場合はグラフィックソフト上では再現しきれません。
実際に軽くコードも書きながら挙動を確かめるのをオススメします。

あるいはレスポンシブデザインの場合、全てのブレイクポイントの画面を作るのは現実的でないかもしれません。
この場合もUIツール上での作業時は「代表的なレイアウトのスナップショットを再現するだけ」と意識しておけるとベターです。

ただしあくまで「**テンプレート化できるようなプロダクトの場合**」だけ考え、そうでなければ最初のうちはスキップします。
業務アプリケーションであれば機能が体系立っているでしょうが、特設サイトみたいなものだとコンテンツがページごとにガラリと変わるかもしれません。

先にある程度、枠や制約を作った方が効果的な場合だけ考えます。

## 小さな単位のコンポーネントを作る

ようやくデザイントークンが設定し終わりました。次に小さなコンポーネントを作っていきます。

### HTML Elementを満たせる粒度

最低限何のパーツを揃えれば良いのか？という話題はよく挙がりますが、自分はHTML Elementを満たせるくらいのバリエーションがあれば良いと思っています。

#### nav

- navが必ずしも同じ見た目とは限らないけど、グローバルナビゲーションなど、よく表示されているものはあるはず
- 現在地がアクティブになっているバージョンや、子階層を表示しているバージョンなど、プロダクトによって必要な情報は結構変わってくる
- また、プロダクトが長く続けば大抵ナビゲーションアイテムが増えるため、多少は拡張出来る作りにしておくとベター
    - どうやったってこのレイアウトじゃないと収まらない……みたいなものを初めに作ると不幸になる

#### aside

- asideはサイドバーのことではないけど、多くのサイトにはサイドバーがあるので紐付けて紹介する
- 実は色々なパターンがある
    - ルートナビゲーションを担っている
    - ナビゲーションかつユーザー情報を表示している
    - アクションやツールがまとまっている（その場合ナビゲーションとは役割が違う）
    - 広告やランキングコンテンツなどが表示されている
- これもアクティブやフォーカスなどのステートが多く存在する
- ユーザーアカウントのタイプや権限によって表示される要素が変わることもあり、その場合は一覧できるようにしておくとベター

#### h1, h2, h3, h4, h5, h6

- hタグのセマンティックと見た目が常に一致するとは限らないものの、目安になるのは違いない
- タイポグラフィを考えるときにフォントサイズは決めたものの、見出しともあれば装飾がつくケースも多い
    - 文頭に■や●などの飾り
    - 下線
    - 背景にザブトンをひく
    - これらの装飾とテキスト自体のセットでコンポーネント化しておく

#### header

- そこまで多くのステートは無いかもしれないけど、通知の有無やログインの有無など、いくつかパターンは考えられる
- コンポーネントを考える時点で、固定ヘッダーなのか？やスクロールすると見た目が変わるタイプか？などを考えておくと良い
    - スクロールすると見た目が変わる→GitHubのプロフィールページなど

#### footer

- footerはさすがにステートレスの場合が多いので、単に繰り返し使えるようにしておけば良いはず

#### hr

- 区切り線
- 同一コンポーネントで、左右のpaddingを0, 4, 8, 12...などで作っておくと意外と便利
    - Appleが配布しているSketchファイルが確かこうなっていた気がする

#### blockquote

- プロダクトによっては不要かもしれない
- 実態は「高さや幅が可変で、引用のマークがついたテキストボックス」程度のコンポーネントになるはず

#### ol, ul, li

- 各種リストの表示の仕方
- マーカーの見た目を考えるのが主
- ネストした際のマーカーの表示の仕方はコードと併せて考えておいた方が良い
    - 見た目次第では子セレクターでの書き方やmargin, paddingの取り方がやたら複雑になってしまう場合がある

#### dl, dt, dd

- プロダクトによっては不要かもしれない
- 背景色の付け方や複数行になったときの見た目の印象など、ある程度確認できておくと良い

#### a

- コンポーネントとして用意するというより、テキストのスタイルとして登録する程度だと思われる
    - 下線つきテキストで、何色にするか？にほぼ終始する
- 別タブで開く挙動のリンクのときはこのアイコンをつける、は初めからルール化しておけると後から苦労しない
    - 厳密に決めるような箇所でもないため、開発者によって選ぶアイコンがバラバラになってしまう場合もある

#### code

- プロダクトによっては不要かもしれない
- 書いたコードを表示する場合、等幅フォントを指定し忘れていると非常に見づらくなる
- UIデータ上でシンタックスハイライトを再現するのはかなり難しいので、表現の仕方は予めエンジニアと相談しておくのが良い

#### table

- 様々な種類のテーブルがあるかもしれないが、デフォルトを定義しておくだけでも十分良い
- レンダリング結果のtableは、セルの幅や改行がUI通りにいかないことも多い
    - そのため厳密なレイアウトをUIデータに求めない方が良い

#### input系

- こちらも様々な種類があり、かつ登場頻度も高い
    - input
        - text
        - time
        - range
        - checkbox
        - radio
        - file
        - などなど……
    - select
    - textarea
    - label（inputと実質セット、という意味で）
- 状態も多いので予め再現しておく
    - 未入力（プレースホルダー表示）
    - 入力済み
    - エラー
    - フォーカス

#### button

- 一口にボタンと言っても相当種類が多い
    - primary, secondary, underline...
    - サイズの大中小
    - 塗り、線
    - アイコンの有無、あるいは左右どちらにつくのか
- 全てのパターンを網羅する必要はなくとも、代表的なものだけは予め用意しておいた方が良い
- Figmaでいえば最近実装されたvariantsを上手く活かしてデータを作ると、それがそのままコードにも適用出来る
    - React Componentだとしたら、どういうpropsを渡したらどう変化するのか？をUIデータの時点である程度ルール化できる
    - これらの話はデザイナーだけで行わずエンジニアも一緒になって話せるとベスト
- `hover`や`focus`などの状態も作っておくと実装時の迷いがなくなる

#### details, summary

- タグとしてdetailsとsummaryを使うかは別として、アコーディオンのUIは大抵実装するはず
- 閉じているとき、開いたときの見た目を定義しておく
- アニメーションも考えておけると実装時に迷わなくなる

### 色々な場所でよく見るUI

HTML Elementで定義できるほどプリミティブではないけれど、大抵どこでも見かけるようなものも先に考えておけると良いです。

#### アイコン

- Font AwesomeでもMaterial Iconでも、どのアイコンセットをデフォルトで使うかを決めておくと楽
- ちなみにiタグはアイコンではない

#### タブ

- アクティブ、非アクティブの状態
- アイテム個数が変わっても大丈夫な作りにしておけるとベター

#### カード

- カードに表示する中身はプロダクトによると思うので割愛
- ただし、情報が多いバージョンと少ないバージョンである程度見た目の一貫性を考えておくのは必須
    - 情報量が変わるとレイアウトや色使いが完全に違ってしまうUIを見かける
    - かくいうQiitaも……

#### ダイアログ

- 場面によってダイアログ内の情報量は変わるだろうけど、ボタンの位置や重要テキストの位置は揃えておく

#### スナックバー

- スナックバー単体を考えるというより、画面のどこに出すかを考えるイメージ
    - 何も考えないで`bottom: 0;`で指定したらフッターとかぶってしまうかもしれない、など
- そしてアニメーションや表示持続時間の設定も考えられていると良い

#### パンくずリスト

- デスクトップの場合はそこまで考えることもない
- モバイルで階層が深い場合、折りたたむとか横スクロールとか色々なパターンが考えられる

#### モーダルウィンドウ

- こちらも表示する位置や、背景を暗くするのかどうかなど、周辺の要素を考えておく必要がある
    - 外側クリックで閉じるのかなどエンジニアと相談すべき箇所もおそらく多い
- 個人的にはモーダルウィンドウは嫌いなのであまり使いたくないけど、大抵必要

#### ドロワー

- サイドバーを開閉出来るだけ、という場合もある
- 開閉アニメーションなどは予め考えておきたい

#### ツールチップ

- 固定幅にするのか、max-widthを設定するのか、などは考えないといけない
- 長い文章が入ってしまうと容易に読みづらくなってしまう（特にモバイルでの表示）

## まとめ

私はデザイナーになってからというもの、会社でも個人開発でも新規プロダクトに携わる経験がそれなりにありました。

一度自分の中で暗黙知になっていそうな内容をdumpしようと思って記事を書いたのですが相当な分量になってしまい、もっと早く記事化すれば良かったなあと思っています。

こういった内容はあまり体系立っていない印象があるので、どなたかのお役に立てたら幸いです！

## 最後に

[Ateam Group Manager ＆ Specialist Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam)の2日目は @tsutorm がお送りします！「**明太子の日**」についての何かを書くそうなのですが、一体どんな内容になるのでしょうか……？