interfaceのあるデザインシステム、ないデザインシステム

経緯


昨年、デザインシステムについて色々と考えたり、まとめたりしました。

blog.dr1009.com

blog.dr1009.com

blog.dr1009.com

この背景に「Material Design 3の発表」を見て衝撃を受けたことと、「FlutterとReact Native、Android SDKiOS SDKによる開発体験の違い」を考え始めたことがあります。 Material Design 3についての考えはそのままのタイトルでブログにまとめ、半年以上経っていますが、考えは現時点でもあまり変わっていません。

このブログは、後者について考えるために『デザインシステムを開発手段として見直す』ことを目的としたブログです。 前回「デザインシステムという仕組みは、一般化できないのではないか」とまとめた話を、なぜ纏めることができないのか整理したものになります。

なお色々と考えていたら、変にまとめるとまとまらない気がしてきたので、書きたいことを書きたい順に書きます。 今回のブログをFlutterを使う時にどう活かすかや、React Nativeをなぜ選ぶべきかについては、次に纏める予定です。

デザインシステムの違いと実運用

Web

数度書いている話ではありますが、基本的に「デザインシステム」はそれぞれのシステムの総称であって、ある仕組みを持つ細かな箇所が異なるシステムとは見做しません。 一方で、ある程度話をまとめないと個別の話に終始してしまいます。 このため、ここでは「Webのデザインシステム」という単語でCarbon Design SystemPolarisをまとめます。


まずWebの「色やサイズの指定」は、HTMLの要素とCSSの組み合わせで表現されます。

developer.mozilla.org

CSSは、誤解を恐れずにいうならば、非常に簡素なシステムです。 それゆえに複雑に組みあわせることで、レイアウトやデザインを自由度が高く実装することができます。*1 また、この指定は「Webのドキュメントとして妥当な状態を保つために」適切に指定することも求められます。 このため、何のルールもなく作るのではなく、根拠のあるルールのもとで自由度が高くカスタマイズする世界になっています。

一方、Webの世界における「コンポーネント」は(何もしなければ)ブラウザに依存します。 わかりやすい例として、DatePickerを例示します。

b-risk.jp

このブラウザによる振る舞いの違いは、特定のブラウザを利用している場合に不具合となることがあります。 このため、「複数のブラウザ上で、同一の体験をする」ようなコンポーネントが用意されます。

www.carbondesignsystem.com

私の理解では、こういった「ブラウザごとの振る舞いを吸収する」ことと、「サービスとして必要なトーンの統一を行う」ことの2点から、デザインシステムが構築されます。 この時、アトミックデザインという考えを利用するとコンポーネントが整理しやすいため、採用される傾向があるようです。 *2


WebではHTMLとCSSという非常に簡素な要素をベースとしているために、なんらかの「すべてのデザインシステムが共通するシステム」が存在していないようです。 「あるデザインシステムが別のデザインシステムに影響を与える」というのは、概念上の関係性です。 このため、先行していたり著名であったりするデザインシステムを、それぞれRespectして運用されるのが、Webの文脈におけるデザインシステムの立ち方と理解しています。

iOS

iOSでは、Human Interface Guideline(HIG)というガイドラインが大前提にあります。 すべてのiOSの標準コンポーネントは、HIGに従って構築されます。

developer.apple.com

HIGが対応しているのはiOSだけではなく、macOSやwatchOSも含まれますが、一旦話をiOSのみに閉じておきます。


では、iOSにおける「HTMLやCSS」とは何なのでしょうか?

確かに、UIViewの背景色を変更したり、paddingの調整をしたりすることはできます。 しかしこの時に指定しているのは「Webで言うところのCSS要素」であるものの、「WebのCSS」を操作するわけではありません。 あくまでも「UIViewクラスの、変更可能な要素」を変更することで、近い結果を得られるだけとなります。

developer.apple.com

stackoverflow.com

また、iOSは「OSのバージョンごとに、コンポーネントのデザインが変更される」システムです。 最近(2022年ごろ)では、Headerの変更が記憶に新しいところです。

developer.apple.com

iOSにおけるコンポーネントは、iOSという単一のプラットフォームではありますが、OSの思想によって更新されるものです。 結果として、iOSのUIKitを利用しているアプリケーションでは、その更新の影響を受けることになります。 UIKitのなんらかのコンポーネントを継承して利用している以上、コンポーネントの変更がある場合には、その影響を「必ず」受けるという事実があるのです。

iOSのアプリケーションを作る際、もしも「すべてのUIKitのコンポーネントをカスタマイズせずに」利用していれば、常に「最新のiOSに適合した」アプリケーションとなります。 それゆえ、「UIKitのカスタマイズ」はカスタマイズした側の責任で持って、対応を行わなければなりません。 この対応が困難なのは、ただiOSソースコードや開発状況が非公開であるがため、何が変わったかをドキュメントと結果から推測しなければならないためです。

同様の難しさは、色やフォントの設定で顕著になります。 iOSのUIKitが用意している色やフォントを、UIKitが提供する通りに利用している限り、iOSの更新に適応するのは(比較的)簡単です。 しかし、「独自のカスタマイズ」を行うためには、「iOSの提供する仕組みを把握し、iOSの提供する仕組みに合致するように、独自のカスタマイズを行う」必要があります。


iOSのUIKitには、UIKitの「テーマ」を設定する仕組みが(現時点では)ありません。 このため、各コンポーネントごとに設定を行う必要があります。 *3

この「各コンポーネントごとに設定を行う」ことでアプリケーションごとのUIを作り上げると言う取り組みは、Webにおけるアトミックデザインを取り入れた手法に近くなります。 結果として、この2つのプラットフォームへの取り組みは「同じ方法で実現されている」と捉えられているようです。

Android

Androidは、話がややこしくなります。 なぜかといえば、Material Designがない状態、適合していく途中の状態、統合し前提となった状態が存在するためです。


Androidには、古くから*4Themeという仕組みがあります。 これはアプリケーション全体の色や表示に関する設定をまとめる仕組みです。

developer.android.com

このThemeは、デフォルト設定として利用する色などの設定を定義するものであり、画面やパーツを「アプリ全体」か「ある箇所」で変更するために利用するために利用します。 いわば『Androidは「Viewの色などの設定を、全体/個別にカスタマイズする」システムが組み込まれたプラットフォーム』です。

Material DesignAndroidのアプリケーションに適用するため、Themeの概念を取り入れています。 そして、Material DesignThemeによるViewのカスタマイズが前提となったシステムになります。


少し話は飛びますが、宣言的UIであるJetpack ComposeFlutterでは、Themeはクラスになります。

developer.android.com

api.flutter.dev

Material Designが適用されたコンポーネントでは、これらのクラスで定義された設定が反映されます。 つまり「Themeというinterfaceを利用している」のが、Material Designを適用したコンポーネントとなります。

このため、「Themeを無視したカスタマイズ」と「Themeを利用したカスタマイズ」が全く別の意味合いを持つこととなります。 これがAndroidコンポーネントにおいて、アトミックデザインの手法を取り入れにくい状態を作り出している、と筆者は理解しています。

システムが想定するカスタマイズと想定しないカスタマイズ

多くの場合、デザインシステムは「構築するもの」であったり「適用するもの」として話題に上ります。 これはアプリケーション、つまりサービスそのものに着目し、ユーザー価値を高めるという意味で正しいあり方です。

一方で、単に開発者の生産性という文脈でも語られることがあります。 これは「再利用可能な要素」があれば、画面ごとのアドホックな開発を避けることができるという文脈になります。 特にスタートアップなどの「素早く、効果的に」開発をする文脈では重視するべき項目です。


自社向けのデザインシステムを作るとき、Webのように「0から作る」こともあれば、Andorid(MD)のように「カスタマイズ可能なところを抑えて作る」こともあります。 デザインシステムが特定のプラットフォームに対応するものであれば、そのプラットフォームの流儀に則るのが、最も手早く安定した方法となるはずです。

この時に「プラットフォームによって、ベースとなるシステムが違う」ことを意識することが重要になるのではないか、そう感じています。 また、マルチプラットフォームフレームワークを採用する時には、ベースとなるシステムがあるもの(ex. Flutter)とないもの(ex. ReactNative)でとるべきアプローチが異なるはずです。 より良い開発、そしてアプリケーションの実現のために、色々と考えていきたいなと思っています。

*1:とはいえ大変です

*2:アトミックデザインがコンポーネント構築に利用されることの是非については、ここでは触れません

*3:なお、SwiftUIを採用してもこの観点では違いがないように私は感じています

*4:Material Designの登場以前から