概要
UIに関するTipsで、次のようなものがよく流れてきます。
「角丸がかかっている要素の内側に、更に角丸の要素を配置するときは内側の角丸 = 外側の角丸 - 間の余白
にすべし」というものです。
このルール自体は数学的にも理にかなっており、外側と内側の角丸の余白面積を均一にする法則として機能します。
しかし、このミクロなTipsだけに注目してしまうと、アプリケーション全体の設計において重要な視点が抜け落ちてしまいます。
角丸の設計においても、個別の要素レベルでの最適化から一歩引いて、全体での一貫性を考慮したマクロな設計が必要なのです。
この記事では、角丸設計において「木を見て森を見ず」にならないための考え方と、実装時の具体的な対策について紹介します。
対象読者
- UIデザイナー・フロントエンドエンジニア
- デザインシステムの構築・運用に関わる方
- プロダクト開発でデザインと実装の両面を考慮する必要がある方
この記事で得られること
- UIの角丸における全体最適化の考え方
- 実装可能なデザインシステムのアプローチ
- チーム状況に応じた現実的な判断基準
結論
角丸ありきの階層に制限を設ける、コンポーネントでは階層ベースのAPI設計を行う、または意図的に対応を控えるなど、チームの状況に応じた選択が重要です。
問題点
階層設計に言及されていない
よく紹介されているTipsでは、2階層の場合についてのみ言及されています。
しかし、実際のプロダクト開発では、更に多くの階層が必要になるケースも発生します。
階層が増える例:
- カードコンポーネント内に注意書きや警告エリアが必要になる
- 複数のカードをグルーピングするための外枠が必要になる
- フォーム内でのセクション分けが必要になる
- ダッシュボード内でウィジェットを整理するための階層が必要になる
このような場合、元の法則を機械的に適用し続けることはできません。
もし外側20px、余白は常に8pxの場合、3階層目で値がマイナスになります。
階層1: 外側20px → 内側12px
階層2: 外側12px → 内側4px
階層3: 外側4px → 内側-4px ← 破綻
また、無制限に階層を増やすことで、一番外側と内側で角丸の度合いが大きく変わり、ビジュアル全体での印象が統一されなくなります。
3階層も4階層も必須になることは少ないですし、仮に必要でも角丸に頼らない見せ方をすれば良いのですが、それを暗黙の了解にしておくのも良くありません。
では逆に、外に行けば行くほど大きくすれば解消するのかというと、そうでもありません。
分かりやすいのはBentoグリッドでの場合でしょうか。
見た目の統一感のために、一番外側の角丸は揃えておきたいです。
しかし、外に行けば行くほど大きくするというルールで組んでしまうと、階層数によってバラバラになってしまいます。
コンポーネント設計における曖昧さ
現代のフロントエンド開発では再利用可能なコンポーネントベースでの設計が主流です。
それぞれのコンポーネントは、責務の範囲からして、自分自身がどの階層で使用されるかを事前に知っているべきではありません。
しかし、角丸の余白法則はそのような状況を想定できていないと思います。
よく問題となるであろうコンポーネントの例:
- ボタン:単体使用、カード内、モーダルウィンドウ内、フォーム内など様々な場所で使用される
- インプット:フォーム、検索バー、設定画面など多様な文脈で使用される
- アバター:ヘッダー、コメント、ユーザーリストなど階層の深さが異なる場所で使用される
- アイコン:ボタン内、リスト項目内、通知内など階層によって扱いが変わる
これらのコンポーネントに対して、角丸調整のルールを適用するかどうかから設計する必要があります。
適用する場合、以下のような実装上の課題が発生します:
実装レベルでの課題:
- 角丸の値自体をpropsとして渡すのか
- 階層の深さを表す情報をpropsとして渡すのか
- 親コンポーネントから自動的に階層情報を取得するのか
- デフォルト値の設計はどうするのか
イメージとしては、このようなバリエーションが出てくると思います。
どれがベストということもないので、組織の状況やプロダクトの性質などに合わせて見極める他ありません。
// パターン1: 角丸の値を直接指定
Button radius="m" />
// パターン2: 階層の深さを指定
Button depth={2} />
// パターン3: Context経由で階層情報を取得
LayerContext.Provider value={{ depth: 2 }}>
Button />
LayerContext.Provider>
対策
上記のような課題を解決するために、このようなアプローチが考えられます。
ただし、これが正解というよりは、私の経験に基づくヒューリスティックな判断です。
角丸の階層数の制限を設ける
最も効果的なのは角丸ありきの階層数に明確な制限を設けることです。
私の経験では、2階層までに制限するのが現実的かと思います。
2階層までであれば角丸の度合いが極端に変化することを防げ、全体として見た目の一貫性を保つことができます。
また、開発者にとっても理解しやすく、実装時の判断コストを削減できます。
ただし2階層を超えてグルーピングや情報の階層化が必要になる場合もあると思います。
その場合は背景色を使わないとか、線によって区切るなど、角丸を使わない方法で視覚的な分離を図ります。
コンポーネントのAPIを階層ベースで設計する
コンポーネントでは、角丸の大きさではなく、使用される階層の深さを表現するAPIを設計することを推奨します。
// 推奨しない:具体的な数値やバリエーション指定
Card radius="12px" />
Card radius="m" />
// 推奨する:階層の深さを表現
Card depth={1} />
Card depth={2} />
このアプローチにより、以下のメリットが得られます:
設計面でのメリット:
- デザインシステムの意図が明確になる
- 階層の概念がコードレベルで表現される
実装面でのメリット:
- 開発者が迷うことなく適切な値を選択できる
- デザインシステムの変更が自動的に反映される
具体的な数値やバリエーションを指定する方がぱっと見は簡単だと思うのですが、どこがMサイズの角丸でどこがLサイズの角丸か、というのはかなり恣意的です。
そのため、階層ベースを提案しています。
なお、更に厳密に管理したい場合は、親コンポーネントで階層数をインクリメントし、子コンポーネントに自動的に伝播させる仕組みを構築することも可能です。
意図的に対応を控える、という選択肢
ちゃぶ台を返すようですが、そもそもこの対応を行わないという選択肢もあります。
角丸の余白法則は確かに視覚的な美しさを向上させますが、その効果と管理コストを天秤にかけた場合、必ずしも実装する価値があるとは限りません。
実装しない場合のメリット:
- デザインシステムの複雑さが軽減される
- 開発者の学習コストが削減される
- 新しい要件に対する柔軟性が向上する
実装しない場合のデメリット:
- 細部の視覚的な美しさが、多少損なわれる可能性がある
多くのプロダクトにおいて、角丸の微細な調整よりも、機能性や使いやすさ、開発効率の方が重要である場合があります。
特に、チームの規模が小さい場合やスピーディーな開発・改善が求められる場合は、このような細部の最適化よりも、より大きな価値を提供する部分にリソースを集中させる方が良いでしょう。
判断基準の提案
どの対策を選択するかは、チームの状況とプロダクトの要求に応じて決定すべきです。
あくまで一例ですが、以下の判断基準を参考にしてください。
実装を推奨する場合
- 細部の見た目のクオリティが重要な競争優位性を持つプロダクト
- 専任のデザインシステムチームが存在する組織
- 長期的な保守性を重視する成熟したプロダクト
実装を控えることを推奨する場合
- 機能開発のスピードが最優先のプロダクト
- 小規模チームで開発をしている組織
- デザインシステムの学習コストが問題となる環境
まとめ
角丸の余白に関するTipsは、視覚的な美しさを追求する上で価値があります。
しかし、この技法を盲目的に適用するのではなく、プロダクト全体の一貫性と実装の現実性を考慮した上で、適切な判断を行うことが重要です。
美しいデザインを追求することは素晴らしいですが、そのためのルールが開発チームの負担となり、結果的にプロダクトの価値提供を阻害するようでは本末転倒です。
特に、細かなデザインルールを一貫して維持することの難しさは、多くのデジタルプロダクトが完璧に整った見た目を実現できていない現実からも明らかです。
ミクロなTipsをマクロな視点で捉え直し、自分たちの組織の状況と照らし合わせながら、最適な選択をすることが、持続可能で美しいプロダクト開発につながるのではないでしょうか。
今回提示した対策の中から、皆さんのチームに適したアプローチを選択し、一貫性のあるビジュアル作りの一助になれば幸いです。
Views: 0