デザインシステムの難しさ

デザインシステムというものが昨今話題になっています。デザインシステムを簡単に説明すると、デザインとその組み合わせに規則性を持たせることで局所最適を無くしたり、ブランドイメージを担保したり、実装工数を削減したりすることを目的にした基盤作りです。プロダクトが大きくなるにつれデザインシステムの意義が増していくため、プロダクト連携でより大きな価値とユーザー体験を生みだそうというフェーズに会社が入るとこぞってデザインシステムをやりたがる傾向があります(俺調べ)。

デザインシステムの良さというのは語られる場面が多くなったように思います。特にこの領域のアーリーアダプタである Shopify と Adobe によるデザインシステムの公開はインパクトが大きく、デザインシステムをやっていない会社でも Polaris や Adobe Spectrum の名前を頻繁に聞くようになりました。一方で、それらを参考にデザインシステム導入へと動き出した会社はそれほど多くなく、まだまだ自力のある会社の専売特許という印象もあります。

そもそもデザインシステムを構築する上で障害になるのはどういったものでしょうか。ushironoko の妄想の中になぜか色々な経験談があるのでアウトプットしてみます。妄想なのでどう解決していっているかなどの how の部分は書くことができないため、こうすると良さそうだなぁというものを置いておきます。注意点として、いわゆるデザイントークンを作ったりトンマナを考えたりするデザイナーの領分となる話はできません。エンジニアリングの観点からみたものについて書いていきます。

何をデザインシステムとするか

例えばエンジニアが思い浮かべるデザインシステムは以下のようなものです。

  • コンポーネントがライブラリとなっており npm からインストールして使える
  • デザインは figma を master として逐次更新していく
  • デザイナーはデザイントークンが変更される場合その内容を tailwind.config.js などに反映する PR を出す

これらはデザインシステムを運用する上での how になりますが、実際にはじめてみると「何がデザインシステムなのか」という悩みに直面します。例えば以下のような Card コンポーネントのデザインシステムの master があるとします。

含まれるコンテンツの種類によってスペーシングが変わるコンポーネントの図

適当にそれっぽいのを figma で作ってみました。Card コンポーネントの中に入るコンテンツパターンと、そのコンテンツが持つ spacing を設定しています。この spacing はデザイントークンとして定義してありデザイナーが参照します。さらに実装では Tailwind CSS などの仕組みで担保されるためエンジニアも px 数を間違うことはありません。

一方でこのデザイン上のデザインシステムを愚直に実装へ持ち込むことはできません。なぜなら実装上では"コンポーネントの組み合わせ"に関しては制限を設けたくないからです。

Card コンポーネントは実装上どのようなコンテンツでも入れられるコンテナのようなものとして定義することがほとんどです。デザイン上のデザインシステムをそのまま持ってきた場合、既定コンポーネントとなる Card コンポーネントと、contents オンリー、header 付きカード、header + footer 付きカードの 3 種を作る、あるいは 1 つのコンポーネントを props などで変化させて使うかの二択になります。

しかし、デザイン上のデザインシステムは組み合わせが無限です。カード型デザインにおいてカード内のコンテンツに制限がないからです。リストコンポーネントが入ったり、画像や動画コンテンツが入ったり、form が入ったりします。Card の右上に小さなハンバーガーメニューを出したい時もあれば、submit ボタンを起きたくなることもあるでしょう。

またコンテンツによって spacing を変更したい時や、そもそも不要となる時もあるかもしれません。そういった要望に柔軟に対応するために、Card コンポーネントは「なんでもいれられる外側に枠っぽいのができるコンポーネント」であり続ける必要があります。

デザイン上のデザインシステムはデザインの組版であり、デザイナーが一定のルールにしたがってデザインをするためのものです。一方実装では極力シンプルさを保つ必要があります。ではデザインシステムという言葉が指し示すのはどちらなのか?という話になります。答えは両方です。

デザイナーが「これはデザインシステムです」と言った時、エンジニアはそれが実装上のデザインシステムではなかったとしても、デザイン上のデザインシステムであることを理解しなければなりません。反対に、実装上のコンポーネントについてデザイナー側も把握することが重要です。そうしなければ簡単に実装を破綻させるデザインシステムの組み合わせを、デザイン上のデザインシステムに生み出していってしまいます。両者は表裏一体で依存しあっているということを常に認識合わせする必要があります。

デザインシステムで担保されるもの

デザインシステム構築に取り組む人は必ずある種の呪いを受けます。デザインシステムに人々が求めるものは以下のようなものです。

  • ユーザー体験が統一される
  • アクセシビリティが担保される
  • 機能インタフェースが統一される
  • デザインが統一される

使うだけであらゆる課題が解決されます。使わない手はありませんが、それなりのコストがかかります。Select や Datepicker、Popover に代表される実装難易度がとても高いコンポーネントをデザイン拡張という枠を超えて Web 標準の要素から劣化させずに作るというのは豊富な知識と技術力、段階的にアップデートしていく環境が必要です。一方で、デザインシステムを頑張って実装に落とし込んでいる間にもデザインシステムに基づかない実装は日々増えていきます。

しかし、時間をあまりかけず小さく始める場合にも問題があります。それは使うメリットのないデザインシステムは使われないということです。デザインシステムをエンジニアが使うモチベーションは、頑張らなくてもアクセシビリティや見た目や使いやすいインタフェースが担保されるというものです。段階的にリリースしていく場合、特にアクセシビリティに関しては知識・経験不足から後回しにされがちです。作り込んでる時間がないが、作り込まないと使ってくれないというジレンマはある種の呪いのようなものです。これはデザインシステムが規模の大きな会社の専売特許になっている要因の一つだと思います。

幸い、この問題は解消されつつあります。Tailwind CSS では Headless UI、React Spectrum では react-aria などでそれを担保しようとしています。デザインシステムを構築する上でアクセシビリティが担保された状態(もしくはカスタムフックによって簡単に実装できる状態)で開発できるような仕組みを提供しています。

https://headlessui.dev/

https://react-spectrum.adobe.com/react-aria/index.html

特に Headless UI は Vue と React それぞれでコンポーネントを提供しているため、React コンポーネントでライブラリ化したけど Vue プロダクトで使えないからデザインシステムが浸透しない現象を倒せる可能性があります。Tailwind CSS チームはデザインシステムの民主化に取り組んでおり、非常に期待が高まっています。

また、プロダクトでコンポーネントが必要になった段階でプレ実装をそのプロダクト側で行ってしまうことも手です。各所でデザインシステムっぽいやつを作り、デザインシステム本体へバックポートしていけばデザインシステム実装側も楽ですし、完成品を取り込む時も少ないペインで作業できます。

デザインシステムは難しい

デザインシステムはデザイントークンを作り切った後の実装からが本番です。デザインだけでは価値を届けられないため、常に実装面の課題を突きつけられます。生半可な覚悟で始めることは出来ない高尚な取り組みだと思います。

一方でアーキテクチャが参入ハードルを下げてくれていることも事実であり、今後さまざまな企業がこういった"経験談で語られない苦しみ"を経験して業界全体の知見が高まっていくことが予想されます。自分も機会があれば関わってみたいです。