我が Design-Frontend Ops論〜フロントエンド開発を加速するためのデザイン - 仮説編〜
先日こんなツイートをしたのですが
思いの外反響があり、もっと具体的に聞いてみたい・ディスカッションしてみたいというお声をいくつかいただきました。
せっかくの機会なので、現状自分が考えるデザインとフロントエンドの接合の最適化、カッコ良くいうと「Design-Frontend Ops論」を語っていこうかなと思います。
※ 予防線貼っておくと、まだ全然実践できていないので話半分に聞いてください。タイトルに"仮説編"とついているのはそのためです。
※ 一緒に探求してくれる気概あふれるデザイナーも募集中。
言葉の定義
初めに、人によって考え方がブレないよう、この記事における言葉の定義をします。
デザイン
「デザイン」という言葉は非常に多様な意味で捉えることができますが、この記事においてはデザインとは以下を目的に作られる中間成果物として定義します。
- ユーザやステークホルダーに使ってもらう仮説検証としての目的
- UI がどう見えるかを記述した実装者への連携としての目的
二つ大きな目的が混ざっているのですが、二つ目の実装時に指針となるドキュメントを作るものと同じものを使ってプロトタイプが作れるので、大体のケースで一つの成果物でこの二つの目的を満たしているのかなと思います。もちろん仮説検証したいものによっては別途プロトタイピングツールを使ったり、実装までしちゃうこともあるかとは思います。
"中間成果物"とわざわざ表現している理由は、ここでプロセスが分断されていることを明示するためです。詳細は昔に以下の記事に書いたのですが、個人的には "デザイン" として作るものと "フロントエンド" の成果物として作るものは現状どうしても分かれてしまうものなのかなと考えています。
ざっくり説明すると、デザイン自体を考える時もそうですし、クイックに仮説検証を繰り返す上でも 実装 という手段はいささかコストが高すぎるのではないかと思うからです。
この前提があるが故にデザインとフロントエンドはイコールにならず、それらの接合を考える必要があるのかなと考えています。
なので、この前提が崩れるソリューションが未来に未来に現れた場合には今回考えたことは意味がなくなることでしょう。
フロントエンド
これは難しいことなく、実際にユーザが触る、 Web ブラウザ上で動くコードの実装を指します。あと広義の意味ではネイティブアプリなども含むと思うのですが、一旦この記事では Web のみをスコープとします。(あまり本質的な理由ではないのですが、単純に筆者がネイティブアプリ開発の経験がなく間違ったことを言ってしまうかもしれないため)
Design-Frontend Ops
ちょっとカッコつけて呼びましたが、ざっくり言うと「デザインとフロントエンドをどう連携させると全体的な生産性が高まるか」を指します。
生産性の定義は難しいのですが、プロダクト開発においては「仮説検証をなるべき速く繰り返し行い、正しい答え(機能案など)にたどり着くこと」と「速くデリバリーすること」の二つの観点が大きくあるのかなと考えています。
前者に関しては Design-Frontend の文脈でできることが何かあるかもしれないですが、自分がマジでプロトタイピングの経験がなくあまりいいアイデアが思いつかないので省きます。将来的にやっていきたいとは思っているので、そこで何かを学んだら別途発信していこうと思います。
この記事では主に後者の「速くデリバリーすること」についてフォーカスして考えていこうと思います。
結論として思っていること
初めに結論から述べると、私が思う「速くデリバリーする」ための最強の Design-Frontend Ops 論は
デザインからそのまま利用可能なフロントコードが生成される状態
を保つことです。
デザインからフロントエンドの連携で一番生産性が高い状態 = それは全く時間がかからないこと = デザインからそのままフロントコードが生成できること、という至極簡単な理論です。頭悪そうですが本気でこう思っています。
また、サブ目的として
「ステークホルダーやユーザに使ってもらう仮説検証としての目的」を
生産性高く達成できる状態を保つ
というのも含めたいと思います。なぜなら、この目的を考えないなら「最初からフロントのコードでデザインも作っちゃえばいいんじゃない?」という発想になりかねないからです。繰り返しにはなりますが、現状デザインとフロントエンドは成果物の形として分断せざるを得ないと思っているので、あくまでデザインの他の目的である「仮説検証をクイックに繰り返し行える」という価値を毀損しないことを前提にしたいと思います。
という訳で、これを実現するために何が必要なのかを具体的に考えていこうと思います。
「デザインからプロダクションで利用可能なフロントコードが生成される状態」を維持し続けるためのデザインシステム
結論ありきみたいな話になってはしまうのですが、上記目標を実現するにあたって重要なのがデザインシステムの構築と運用だと思っています。
まずデザインからフロントコードを生成するにあたって、重要なのが「デザイン自体の作り方」と、「デザインとフロントエンドのコードを同期すること」です。
デザイン自体の作り方
これは実際に実装されるのと同じ構造で作るということを指します。例えばリストは HTML 上では ul, li タグで表現されるべきですが、次のようにデザイン上で一つのテキストで表現してしまうと機械的にこれがリストと解釈することは難しくなります。
また、Figma で言う Auto Layout などを厳格に運用する必要があります。なぜなら見た目だけの情報ではどうレスポンシブにレイアウトされるのかと言う情報が全くなく、全てを absolute な配置にしても実際のフロントエンドでそれをやると破綻してしまいます。
デザインとフロントエンドのコードを同期する
デザイントークンやコンポーネントがデザインとフロントエンドのコード間で一致していることを指します。
そこまでポピュラーな語句でもないので解説すると、デザイントークンというのは色やタイポグラフィ、シャドウや余白の値など、デザイン全体で統一したい値を数値化・定数化したものを表します。
もっとイメージしやすいように言うと CSS なんかでテーマとして色を変数管理したりすることがあると思いますが、そんな感じで扱うもののことです。
$blue-400 = #2680EB;
$white = #ffffff;
また、コンポーネントについては言わずもがなですが、UI をある程度の粒度で分割したものです。この粒度がデザインとフロントエンドで違うと、即ちどちらか一方にしかないコンポーネントが存在しているとそれは 1:1 でマッピングできないため自動的に作ることができません。逆に言うとこれがマッチすると素直に生成することができます。
この2点がデザインデータから実用的なフロントエンドのコードを生成する状態を作るのに必要不可欠で、そして、これらを維持し続けていくための How としてデザインシステムがあると考えています。
なぜなら、上記のようなことはデザインの作り方に一定の制約を加えることであり、その制約はデザインシステムで実現したいことだからです。
デザインシステムってなに?
多分100%「これだ!」という定義は無いと思うので、「Design Systems」という本から引用します。
デザインシステムとは、デジタルプロダクトの目的を達成するために首尾一貫したルールで編成された、お互いに関連づけられたパターンとその実践方法です。
なんとなく伝わったかもしれないですがもう少し具体的にイメージするために、実際に Shopify の Polaris というデザインシステムを見てみようと思います。
Polaris では色やタイポグラフィに関して原則や具体的な値などのルールを定義しています。
https://polaris.shopify.com/design/colors#navigation
また、ソフトウェア全体で再利用可能な UI パーツとしてコンポーネントも定義してます。
以下に一例としてボタンコンポーネントの画像を貼りました。
https://polaris.shopify.com/components/get-started#navigation
このように言語化したデザイン原則に則して、一貫性のある UI を作るためのパターンを定義するものがデザインシステムです。
デザインシステムは本来的には体験の一貫性を整えたり、システムに則ってデザインすることによって生産性を上げることを目的に作るものだと思いますが、それが結果的にはフロントエンドの生産性の寄与にも付与するものだと考えています。(ちょっと私がデザインシステムエアプなので、もしかしたらこのデザインシステムで定義するものが「デザインとフロントエンドで 1:1 でマッピングできる」という前提が間違っている可能性はあります。)
デザインの作り方はどうフロントエンドの実装に影響を与えるのか
という訳で上記の理想に辿り着くにはデザインとフロントが同期されたデザインシステムが必要なのではという話をしました。
しかしデザインシステムは一朝一夕でできるものではなく、また、デザインシステムは一回作ったら終わりというものでもありません。
つまりある程度手動で作る機会は存在し続けます。なので、このセクションでは手動でフロントコードを実装することを前提として、デザインを作る上でどんな要素が実装に影響を与えるかを考えていきます。
ツールに Figma を使う
特定のツールを前提にしちゃうのはアレなのですが、私は上記を実現するためには Figma が必須というか、他のツールでは実践できないのではないかと考えています。現状デザイン - フロントエンドのコラボレーションを支えるツールとして Figma が最強です。
なぜ Figma がいいのか、具体的などんな機能が必要と考えているのかは次の通りです。
- 要素ごとの属性値や要素間のマージンの値が取得しやすい
- デザイン上がクラウド上に存在しており、いつでも同期できる
- レイアウトを表現するための Auto Layout
- プラグイン/API などを通してプログラマブルにデザインデータにアクセスできる
- variants でコンポーネントの状態の変化が表現できる
いっぱいありますね。順に詳しく解説していきます。
要素ごとの属性値や要素間のマージンの値が取得しやすい
実装する時には、当たり前ではありますがデザイン上の具体的な値を取得する必要があります。色だったり、タイポグラフィの値だったり、要素間のマージンの値が何pxかだったりです。
マージンの値が簡単に見られる図
Figma は UI 開発を目的においているからかこれらの値が簡単に取得できます。
他のツールの辛みに関しては下記に書いたことがあるのでよければご参照ください。私はもう Figma 以外のツールで実装したくありません。
デザイン上がクラウド上に存在しており、いつでも同期できる
デザインというのは反復的に修正されるものです。修正する度にファイルのやり取りをするなど正気の沙汰ではありません。もしそんなしょうもないことに時間を使っているのでしたら、もっとプロダクト開発にちゃんと向き合ってください。
という訳で Figma のようにクラウド上にデザインが存在していて、いつでも同期できることはデザイン - フロントエンドのコラボレーションにおいて必須です。どうぞよろしくお願いいたします。
レイアウトを表現するための Auto Layout
神機能です。多分これ無かったらレイアウトのスタイル取れないから、こんなデザイン -> フロントエンド生成しちゃおうみたいなの考えなかったんじゃないかな。
Auto Layout では中身の要素の大きさに応じて Frame が伸縮します。また並び方も CSS の flexbox と同じモデルで指定することができます。
デザインの生産性・メンテナビリティ向上という点でも神ですし、エンジニアに取ってもレイアウトのスタイルが取れたりして神です。
即ち…神です。これ無しのデザイン生活はもうあり得ません。
プラグイン/API などを通してプログラマブルにデザインデータにアクセスできる
ここまである重要なことに触れてきませんでした。
それは「どうやってデザインからコードを生成するの?」ということです。
ご安心ください、Proof of Concept としてこんなものをすでに作っておきました。
Figma から React コンポーネントを生成するプラグインです。
Figma の素晴らしいところはプラグインや REST API を通してデザインデータにプログラマブルにアクセスできる点です。このため、Figma 内のデータを使ってやろうと思えばなんでもできちゃいます。我がフロント生成しちゃおう構想にはこの仕組みが必須です。
variants でコンポーネントの状態の変化が表現できる
コンポーネントというものは複数の状態を持ちます。例えばボタン一つとっても色んな Theme があったり disabled の状態があったりします。
これをデザイン上で一つ一つ個別のコンポーネントとして定義してしまってはフロントエンドのコードと一致しなくなります。
そんなあなたに Figma の variants です。
この機能を使うと複数のコンポーネントを状態によって切り替えることができます。
これもまたデザインのメンテナビリティという意味でも重要ですし、エンジニアに取ってもどう変化するのが分かりやすくありがたい機能です。
理解しやすい・値が取りやすいデザインの作り方をする
例として「リストを単一のテキストで表現してしまうが故に、アイテム間のマージンが分からない」という作り方は NG です。
これをされると詳細なマージンの値が分からず困るからです。このように「どう作られるか」の意識が欠けているが故にフロントエンドエンジニアに余計な「よしなにする力」が求められる場面はままあります。
上記のような実際の実装と構造が変わってしまうような作り方の例は下記記事に書いてみたのでよければご参照ください。
マージンの表現の仕方、 Spacer で表現する作る
細かい話ですが、Auto Layout 内のマージンが異なる場合には Spacer を使うのがいいのではないかと考えています。考え方を昔下記の記事に書いたので引用します。
レイアウトに関して親が構造を規定しない場合、 margin は誰の持ち物でもなく、独立した存在であると考えることができます。
ある要素とある要素の間に余白を作る時は「余白はこっちに紐づいているな」などとは考えず「これらは同じ概念のものだから余白は小さめ、これらは全然違うからもっと離そう」など、それらの要素の "関係性" に基づいて決めているはずです。
なので、 margin はどちらにも属さず、 margin を持つという一点のみに責務を持った存在であると考えられます。
Design-Frontend Ops で他に考えられること
以上、「どうデザインを作るとフロントエンドの生産性が上がるか」という観点で考えてきました。
ただ、もっと他にも全体の生産性を高めるためにできることもたくさんあると思います。
最初にさりげなくスコープ外にした「仮説検証をなるべき速く繰り返し行い、正しい答え(機能案など)にたどり着くこと」という目的に関しても、フロントエンド側で意思決定に必要な情報を取れやすくしたり、状態を持つようなアプリケーションをプロトタイピングに使えやすくしたりなど貢献できるところは色々あるのではと思っています。
また、どうしても不完全なデザイン・不完全な実装というのは出てくるので、そういった小さい綻びをクイックに修正するワークフローというのも磨きがいがあるなと思っています。
全部自動化できたら理想ではありますが、それを完璧に維持するのはそれはそれでコストがかかり ROI が低くなることもあるでしょう。なるべく自動化できるところは自動化しつつも、柔軟性も持ったワークフローを作っていけたらなと思います。
おわりに 〜次回予告〜
冒頭にも言ったのですが、私はデザインシステムの運用未経験です。一応 Shopify という公開されてるデザインシステムを通して生成ができることの仮説検証はできましたが、実際にそれでプロダクト開発をしたことはありません。
もはや何年後になるのか不明ですが、いつか自分で今回話した内容を実践して最高にスピーディなプロダクト開発が実現できるのかを試してみたいです。
おそらく実践していく中では想像している以上に様々な課題があるでしょう。そんな生の知見も将来的には発信していけたらなと思います。
それでは、seya 先生の次回作にご期待ください!!