コンテンツにスキップ

密度

<html>(または任意の祖先)の data-density 属性は、サブツリー全体の コントロールサイズコンテナのパディング / ギャップを切り替えます。 計画 §9.3 が規定するのは 2 つのコントロール変数ですが、 Hypermedia Components は同じ属性をひと握りのコンテナ変数にも拡張して、 レイアウトが均等に締まる / 緩むようにしています — それがないと、ボタンは 縮むのに周囲のカードやダイアログはゆったりしたままで、ちぐはぐに 感じられるからです。

属性--hc-control-height--hc-control-padding-x
(なし) / [data-density="comfortable"]40px1rem(16px)
[data-density="compact"]32px0.75rem(12px)
[data-density="dense"]28px0.5rem(8px)

hc-buttonhc-input は、自身の カスタムプロパティの var() 間接参照を通じてこれらを参照します。 カスケードはこう流れます: data-density--hc-control-*--hc-button-* / --hc-input-* → 描画されたコントロール。

同じ密度属性は、コンテナのパディングと要素間ギャップも上書きします。 これらの変数は component レイヤーに属しますが、密度ファイルが同じ名前を より高い詳細度のセレクタで出力するため、上書きは自動的にカスケード します:

変数ComfortableCompactDense
--hc-field-gap8 px6 px4 px
--hc-toolbar-gap / padding-y8 px6 px4 px
--hc-toolbar-padding-x12 px8 px6 px
--hc-card-padding16 px12 px8 px
--hc-dialog-padding16 px12 px8 px
--hc-dialog-gap12 px8 px6 px
--hc-popover-padding12 px8 px6 px
--hc-alert-padding-block12 px8 px6 px
--hc-alert-padding-inline16 px12 px8 px
--hc-alert-gap8 px6 px4 px
--hc-toast-padding-y12 px8 px6 px
--hc-toast-padding-x16 px12 px8 px
--hc-toast-gap8 px6 px4 px
--hc-table-cell-padding-y8 px6 px4 px
--hc-table-cell-padding-x12 px8 px6 px
--hc-checkbox-size18 px16 px14 px
--hc-radio-size18 px16 px14 px

表にないトークン(角丸、フォントサイズ、バッジ / ページネーションの パディング、ダイアログの最大幅など)は、意図的に密度非対応です。 目的はレイアウトを締めることであって、スタイルを変えることでは ありません。

チェックボックス / ラジオのサイズは 18 → 16 → 14 px と段階します。 dense のターゲット(14 px)は快適なクリックサイズの境界ぎりぎりです — デスクトップのキーボード主体なデータ入力 UI には十分ですが、タッチ ユーザーが含まれるなら周囲のコントロールを大きめにしてください。

smlg のサイズバリアントは密度階層と足並みを揃えて移動するため、 相対順序 sm < md < lg はどの密度でも保たれます。正確な値:

プロパティ密度smmd(デフォルト)lg
ボタン / インプットの高さcomfortable32 px40 px48 px
compact28 px32 px40 px
dense24 px28 px32 px
ボタン / インプットの padding-xcomfortable12 px16 px20 px
compact8 px12 px16 px
dense6 px8 px12 px
チェックボックス / ラジオのサイズcomfortable14 px18 px22 px
compact12 px16 px20 px
dense12 px14 px18 px

以前のイテレーションでは、「明示的な data-size は相対でなく絶対で あるべき」という理屈で smlg を密度階層をまたいで固定して いました。それは逆転を生みました: dense 密度でデフォルトの md ボタンが 28 px に下がる一方 sm は 32 px のままで、サイズの順序が壊れたのです。 現在の挙動は sm / md / lg をアクティブな密度の中での相対的な強調 として扱います。

comfortable がデフォルトです。セレクタ :root, [data-density="comfortable"] により値は無条件に適用されるため、 明示的な data-density="comfortable" と属性なしはまったく同じに 振る舞います。

ライブプレビュー — コントロール

Section titled “ライブプレビュー — コントロール”

以下の 3 つのプレビューは、同じ <button> / <input> HTML を、異なる data-density 属性を持つコンテナの中で描画しています。

カード、アラート、ツールバーも属性を拾います。内部のパディングと ギャップがコントロールと足並みを揃えて締まり、視覚的リズムが比例して 保たれることに注目してください。

Plan summary

Three seats, monthly billing.

Heads up. Two of three seats are unassigned.

Plan summary

Three seats, monthly billing.

Heads up. Two of three seats are unassigned.

Plan summary

Three seats, monthly billing.

Heads up. Two of three seats are unassigned.

ライブプレビュー — テーブルとフォームコントロール

Section titled “ライブプレビュー — テーブルとフォームコントロール”

密度が真価を発揮する場所: データテーブルは目に見えて締まり、 チェックボックス / ラジオのグリフも周囲のコントロールと一緒に縮むため、 フォームの視覚的リズムが保たれます。

MemberRoleStatus
Akira SuzukiEditorActive
Mika TanakaReaderPending
Yuki SatoOwnerActive
MemberRoleStatus
Akira SuzukiEditorActive
Mika TanakaReaderPending
Yuki SatoOwnerActive
MemberRoleStatus
Akira SuzukiEditorActive
Mika TanakaReaderPending
Yuki SatoOwnerActive

密度はターゲットサイズと情報密度のトレードオフです — 階層は好みでは なくポインタで選んでください:

  • comfortable はタッチ向けの階層です。コントロールの高さは 40 px(data-size="lg" で 48 px)で、WCAG 2.5.8 のターゲット サイズ最小値(24 × 24 px)を余裕を持って満たします。主要なタッチ 操作には data-size="lg" を付けると、プラットフォームの HIG (Apple / Material)が推奨する 44–48 px に届きます。チェック ボックス / ラジオのグリフは 18 px ですが、.hc-checkbox-label / .hc-radio-label で包むことでクリック可能領域はグリフよりずっと 広くなります。
  • compactdense はポインタが精密(マウス / トラックパッド) な、情報密度の高いデスクトップ画面向けのプリセットです — データ グリッド、コンソール、管理ツールバーなど。dense ではボタンが 28 px、チェックボックス / ラジオのグリフが 14 px まで下がり、どの タッチガイドラインも下回ります。

タッチ主体の画面に compact / dense を唯一の密度として出荷しないで ください。アプリが密度ピッカーを提供する場合は、ポインタで ゲートします:

<script type="module">
// 粗いポインタ(タッチ)には常に comfortable のターゲットを。
if (matchMedia('(pointer: coarse)').matches) {
document.documentElement.setAttribute('data-density', 'comfortable');
}
</script>

属性を切り替えるのが推奨のリセット方法です。各密度階層は同じ カスタムプロパティ名を自身の属性セレクタ配下で再出力するため (なぜこれで動くのかを参照)、メディアクエリ から参照できる階層別の --hc-*-comfortable 変数は存在しません。 CSS だけで行う代替は値の複製を意味します: 上の表の comfortable 列を レイヤー外の @media (pointer: coarse) { [data-density] { … } } ブロックへコピーします(レイヤー外の author CSS はキットの @layer hc.tokens に勝つため、詳細度の争いはありません)。ただし このコピーはトークンが変わると古くなるため、上記の 1 行の属性 リセットを推奨します。

有用な範囲で、できるだけ DOM の高い位置に属性を設定してください。 たいていのアプリは <html> に置いて、選択がすべてのコントロールに カスケードするようにします:

<html data-density="compact">
...
</html>

より密な UI の単一セクション(例: データテーブルのツールバー)には ローカルに付けます:

<section data-density="dense">
<div class="hc-toolbar">
<button class="hc-button">Edit</button>
<button class="hc-button">Delete</button>
</div>
</section>

コントロール階層(--hc-button-*--hc-input-*)では、トークン ビルドがコンポーネントレベルのカスタムプロパティを var() 参照として 出力します:

--hc-button-height: var(--hc-control-height);
--hc-button-padding-x: var(--hc-control-padding-x);

data-density="compact"--hc-control-height32px に上書き すると、--hc-button-height のすべての消費側が、コンポーネントごとの 明示的なルールなしに新しい値で解決されます。

コンテナ階層(--hc-card-padding--hc-dialog-gap など)では、 密度ファイルが同じ変数名をより高い詳細度のセレクタ ([data-density="compact"][data-density="dense"])で出力します。 カスケードはコンポーネントファイルの :root ルールより一致するブロックを 選ぶため、カード / ダイアログ / ポップオーバー / アラート / トースト / ツールバーの CSS は自動的にアクティブな密度の値を読みます。

コンポーネント単位のカスタマイズはどちらの階層でも引き続き機能します — スコープに --hc-button-height: 56px;--hc-card-padding: 0; を 設定すれば、要素ごとの宣言のほうが具体的なので密度の値に勝ちます。

サイズバリアントと密度は合成される

Section titled “サイズバリアントと密度は合成される”

data-size は 1 つのコントロールがサイズ梯子のどの段に乗るかを選び (「この 1 つのコントロールが大きめの CTA」)、data-density は梯子 全体を動かします(「UI 全体が詰めて組まれている」)。sm / lg の 変数は密度階層と連動して移動するため — 上の表のとおり — 相対順序 sm < md < lg はどの密度でも保たれます。

--hc-control-height --hc-card-padding
--hc-control-padding-x --hc-dialog-padding
--hc-field-gap --hc-dialog-gap
--hc-toolbar-gap --hc-popover-padding
--hc-toolbar-padding-y --hc-alert-padding-block
--hc-toolbar-padding-x --hc-alert-padding-inline
--hc-alert-gap
--hc-toast-padding-y
--hc-toast-padding-x
--hc-toast-gap
--hc-table-cell-padding-y --hc-checkbox-size
--hc-table-cell-padding-x --hc-radio-size

すべて :root, [data-density="comfortable"][data-density="compact"][data-density="dense"] の下で出力されます。