サーフェス
このスキルは、各要素の素材、すなわち塗り、エッジ、影、半径、状態、アイコンを決定します。少数のレシピから選択するため、2つの画面で異なるカードが使われることはありません。
決定を行う前に、product-ui の §1(テイストジャーナルと優先順位)と §5(どのスキルが何を担当するか)を適用してください。
この順序で決定する
- サーフェスは必要か? 追加する前に削除する。周囲にスペースがある見出しにはカードは不要です。カードの中にカードを入れ子にしないでください。理由: コンテナが増えるごとに、目が読まなければならないエッジが増えます。
- どのレベルか? ページ、レイズド、フローティング、またはオーバーレイ。要素ごとに1レベルで、どれだけ目立たせたいかではなく、その要素が何をするかによって選択します。elevation.md。
- エッジは何で描くか? 高低差には影のリングを使います。構造には境界線を使います。1つのエッジに両方を同時に使わないでください。elevation.md。
- どの半径か? 要素の役割に対応するトークンを取得し、入れ子になった半径を同心円状にします。elevation.md。
- どの状態か? デフォルトを磨く前に、ホバー、押下、選択、無効、フォーカス可視をサーフェスの変化としてデザインします。states-and-icons.md。
- どのアイコン処理か? 1セット、
currentColor、ストロークはテキストに合わせます。states-and-icons.md。 - マテリアルは許可されるか? スクロールするコンテンツの上に浮かぶクロームだけです。materials-and-edges.md。
- スクロールのエッジ。 区切り線、フェード、オーバースクロール。materials-and-edges.md。
4つのレベル
| レベル | 用途 | ライトモード | ダークモード |
|---|---|---|---|
| ページ | 基本の背景 | 基本の塗り、影なし | 最も暗い塗り、影なし |
| レイズド | カード、コントロール、選択されたオプション | 白、リング + 1pxドロップ + 3pxタイトドロップ | 1段階明るく、白いリング、タイトな黒ドロップ |
| フローティング | メニュー、ポップオーバー、ツールチップ、トースト | 白、リング + 1pxドロップ + 4pxタイトドロップ | 2段階明るく、白いリング、タイトな黒ドロップ |
| オーバーレイ | ダイアログ、シート、コマンドパレット(スクリムとともに) | 白、リング + 1pxドロップ + 6pxタイトドロップ | 3段階明るく、白いリング、タイトな黒ドロップ |
正確なトークンはelevation.mdにあります。その背後にあるルール:
- リングとタイトドロップ。 ブラー ≤ 8px、オフセット ≤ 6px、ネガティブスプレッドのドロップ。理由: 大きくてソフトなブラーはグローに見え、ページを濁らせ、生成されたように見えます。
- ダークモードでは明るくして高さを表現。 ダークでは影がほとんど見えないため、明るさが高さを伝え、低アルファの白いリングがエッジを伝えます。
- 影は半透明で1色。 不透明なグレーはハローを残します。ダークドロップは黒のままです。
- 同じレベルの兄弟要素は共有する。 1列のカードは、1つの影、1つの半径、1つのパディングを持ちます。
- ホバーは塗りを変え、影は変えない。
参照不要のルール
- 境界線は構造を、影は高低差を示す。 区切り線、入力フィールド、テーブルセル、選択状態は境界線を維持します。持ち上げるためにのみ存在するカードの境界線は、代わりにリングにします。
- 影のリングの下に
border: 1px solid transparentを維持する。 理由: 強制カラーモードでは影が削除され、境界線がエッジを描画し続けます。 - 画像には1pxのインセットアウトライン:
outline: 1px solid黒10%(ダークでは白10%)、outline-offset: -1px。色付きの色合いは絶対に使わないでください(フリンジのように見えます)。ロゴや透過アートワークはスキップしてください。 - 同心円状の半径。 外側 = 内側 + パディング(+ 境界線)、パディングが24pxまで。それを超えると、別々のサーフェスになります。
- フォーカスはリングであり、決してなしではない。
:focus-visibleは2pxのアクセントアウトラインを2pxのオフセットで表示します。フィールドでは2pxのアクセントエッジとして隙間なくぴったりと配置します。outline: noneを代替なしで使うのはバグです。リングはレイアウトスペースを取りません。 - 無効なコントロールはホバー、押下、スケールを受け付けない。
- アイコン: サーフェスごとに1セット、
currentColor、デフォルトはアウトライン、アクティブ時は塗りつぶし。ストロークは隣接するテキストの太さに追従し、400で1.5px、600で2pxまで。 - 背後ブラーはフローティングクロームのみ。 コンテンツ、カード、テーブルには決して使わない。
- スクロール可能なオーバーレイ(ダイアログ、ドロワー、メニュー)には
overscroll-behavior: containを設定する。
ペアの比較
| 悪い例 | 良い例 | 理由 |
|---|---|---|
カードに border: 1px solid #e5e5e5 | box-shadow: var(--elev-raised); border: 1px solid transparent | 高低差だけの境界線はリングになります。強制カラーでエッジを描画し続けます |
box-shadow: 0 10px 40px rgba(0,0,0,.2) | 0 0 0 1px a.08, 0 1px 2px a.12, 0 4px 8px -4px a.16 | タイトで鮮明な方が大きくソフトなものより優れています |
ダークカードに 0 8px 24px #000 | 明るい塗りに加えて 0 0 0 1px oklch(1 0 0 / .08) | ダークでは影が消えます。明るさが高さを示します |
| カード半径8、内側画像半径8、パディング8 | 内側8、外側16 | 同心円状の角は均等な隙間を保ちます |
<img> が白いカードに溶け込む | outline: 1px solid oklch(0 0 0 / .1); outline-offset: -1px | 境界線なしでエッジが読み取れます |
button:focus { outline: none } | button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px } | キーボードユーザーが位置を把握できます |
| 600ウェイトラベルの横に1.5pxアイコンストローク | 2pxストローク | ストロークの太さがステムの太さに一致します |
| すべてのツールバースロットに塗りつぶしアイコン | デフォルトはアウトライン、アクティブのみ塗りつぶし | 塗りつぶしが状態シグナルです |
カードに backdrop-filter: blur(20px) | 不透明なサーフェス | ブラーはスクロールコンテンツの上に浮かぶクロームに属します |
終了前の確認
| パターン | 修正 |
|---|---|
ライトUIでブラー > 8px またはアルファ > .2 の box-shadow | レベルのトークンを使用する |
border と box-shadow が同じ役割をしている | リングと透明な境界線のみにする |
影のリングに border: 1px solid transparent がない | 追加する |
親要素とそのパディング付き子要素に同じ border-radius | 親には inner + padding を使用する |
outline: none または outline: 0 で :focus-visible の代替がない | リングを追加する |
:focus(:focus-visibleではない)でリングをスタイリングしている | :focus-visible に切り替える |
状態によって border-width が変わる | 色、塗り、または同じ幅の透明な境界線にする |
アイコンにハードコードされた fill="#…" または stroke="#…" | currentColor にする |
| 1つの画面に2つのアイコンライブラリがインポートされている | 1つにまとめる |
スティッキーバー、サイドバー、フローティングメニュー以外での backdrop-filter | 削除する |
overscroll-behavior: contain がないオーバーレイリスト | 追加する |
スクローラーの端でのハードカット、または overflow: hidden でクリップされた影 | エッジをフェードする。スクローラーにパディングを追加する |
ライトモードとダークモードを2倍でレンダリングし、各レベルの端を切り取って確認します。各コントロールでホバー、押下、Tabキーでフォーカス、選択、無効化を行い、前後でボックスサイズを比較します。強制カラーを切り替え(Chrome DevTools、レンダリングエミュレーション)、すべてのカードにまだエッジがあることを確認します。