WebアプリケーションのUI構築のポイント
はじめに
UIは小さな判断の積み重ねで体験が決まる。本稿は、誰にとっても分かりやすく誤操作の少ない画面づくりのための実装メモである。
WebアプリケーションのUIデザインについて専門のデザイナー職の方が協力してデザインする場合においては問題は少ないのですが、必ずしも専門ではないWebエンジニアがUIデザインまですることがあります。
目的:
- 非デザイナーでも最低限の操作性・可読性・一貫性を確保できるUI実装の基準を提示する。
対象:
- Webエンジニア、UI実装者、設計/レビュー担当。
前提:
- Fluent 2 Design System と WCAG 2.2 に基づく実装指針。視覚情報に依存しない理解と操作を重視する。参考: https://fluent2.microsoft.design/ / https://www.w3.org/TR/WCAG22/
全体のレイアウト
最初の方針決定が後の迷いを減らす。ナビゲーション、ペイン数、ブレークポイントの選択は、情報設計と実装コストに直結する。
まず、アプリケーションのレイアウト構成を考える。デスクトップであれば2ペイン構成あるいは3ペイン構成なのか。そもそも、デスクトップをメインに据えるのか、モバイルをメインに考えるのか。ということ。
最初に決めること:
- ターゲット優先: デスクトップ優先かモバイル優先か(モバイルファースト推奨)。
- ペイン構成: 1/2/3ペインのどれを採用するか(ブレークポイントでの変化を定義)。
- ナビゲーション: サイド/トップ/タブ/パンくずなどの主要パターン。
- レスポンシブ方針: 主要ブレークポイント、最大幅、余白スケール。
これらの決定に基づき、情報設計と実装の責務分担(フロント/バック)を整合させる。
アクセシビリティ観点の要点:
- ランドマークを明確に: header / nav / main / aside / footer を使用し、1ページ1つの main に限定する。
- キーボード操作を前提に: すべての操作はキーボードのみで可能にし、タブ順はDOM順に一致させる。tabindex>0は原則使わない。
- フォーカス可視: :focus-visible などで十分なコントラストのフォーカスリングを必ず表示する。
- スキップリンク: ページ先頭に「メインコンテンツへスキップ」を設置し、フォーカス時に可視化する。
- レスポンシブ: モバイルファーストの1カラムで読み順を保ち、CSSだけで視覚順を変える場合もDOM順は崩さない。
- タップ/クリック領域: インタラクティブ要素はおおむね44×44px以上を目安にする(対象サイズ)。
- 見出し構造: h1は1つ、h2以降は階層を飛ばさず論理構造を保つ。
メインコンテンツ
メインコンテンツはレイアウトコンテナで包み、余白/横幅/最大幅/センタリングを一括管理する。
内部構造はグリッド+スタックで構成し、可読な読み順と反復可能な間隔を維持する。
アクセシビリティ観点の要点:
- DOM順と視覚順の一致: レイアウトで列入替えを行う場合も、読み上げ/タブ移動が自然になるようDOM順を優先する。
- グルーピング: 関連要素はセクション/fieldset/ul等の適切なセマンティクスでまとめ、見出しで区切る。
- ライブ更新: 動的更新は aria-live="polite" などで通知。頻繁なアナウンスは避け、必要最小限に。
- ローディング: 進行状況には role="progressbar" などを用い、名前/値/範囲を提供。単なるスピナーのみは避ける。
コンテンツの配置
配置の原則:
- 読み順に沿って左→右、上→下へ配置する(視覚順とDOM順を一致させる)。
- 関連は近接、非関連は間隔で分離する。
- 区切り線の多用は避け、余白と見出し構造でセクションを示す。
チェックリスト:
- 見出し/リスト/テーブルなどの要素は意味に応じて使用し、見た目目的の div 多用を避ける。
- アイコンのみのボタンにはaria-labelなどの代替テキストを付与する。
- エラー/状態は色だけでなくテキストでも伝える(例: エラー文を要素直下に表示)。
- クリック可能な領域は十分な余白とサイズを確保する(誤タップ防止)。
- 行間・段落間は読みやすい間隔(例: 行高1.4〜1.8、見出し前後の余白を一貫化)。
色について
色は強力だが、誤用もまた強力だ。色に頼りすぎず、状態と意味を確実に伝える設計にする。
セマンティックカラー
目的:
- 現実世界の慣習(警告/成功など)に沿って状態を即時に伝える。
使用: - 色だけに依存せず、テキスト/アイコン/形状で補強する。
禁止: - 装飾目的のみの使用。
ブランドカラー
使用:
- 製品を表す基調色を選定し、ロール(前景/背景/境界/状態)トークンに落とし込む。
- 目的に応じて濃淡/ステートを定義し、Light/Dark/High Contrastに対応させる。
色に関しての注意事項
- 使用色を必要最小限に抑える(役割ベースの色セットに限定)。
- 状態や意味の提示に色単独を用いない(常に複数手段で伝える)。
- ダークモード/ハイコントラストを前提に、4.5:1以上のコントラスト確保を設計時に検証する。
コントラストの基準
- 通常テキストはコントラスト比4.5:1以上、大きなテキスト(18.66px/ボールド以上または24px以上)は3:1以上。
選択肢が限られ、自由入力が不要ならセレクトが最も堅牢で扱いやすい。 - UIコンポーネント(ボタン境界・アイコン等)と重要なグラフィックは3:1以上。
- フォーカスインジケーターは背景に対して少なくとも3:1以上。
候補が多い、または新しい値を受け入れたいときに力を発揮する。ただし実装は正確さが必要。
状態色とフィードバック
「一つだけ選ぶ」を明快に示す。送信時確定の設定に適する。
- Hover / Focus / Pressed / Disabled の各状態を用意し、状態間でも判別可能な見た目とコントラストを保つ。
- エラー/警告/成功などのセマンティックは、色に加えてテキスト/アイコン/パターンなど複数手段で伝える。
チェックは条件の積み上げ、スイッチは即時反映。目的に応じて使い分ける。
テーマとダークモード
入力体験はフォーム全体の印象を左右する。ラベル・補助・エラーの三点で迷いを減らす。
- 役割ベースの色トークン(例: 背景/前景/境界/状態)を用いて、Light/Dark/High Contrastを一貫適用できる設計にする。
- prefers-color-scheme とOSのハイコントラスト設定を尊重する。
検証
設計の意図は操作して初めて検証できる。数分のセルフチェックで取りこぼしを減らす。
- コントラストチェッカーで主要テキスト/状態/フォーカスを測定する。
- ダークモードやカラーブラインドシミュレーションで可読性と意味の伝達を確認する。
アコーディオン
ガイドライン:
- 見出しはボタン要素にし、aria-expanded と aria-controls で連携、パネル側は id を持つ。
- キーボード: Tabでヘッダーへ、Enter/Spaceで開閉、↑↓で隣接ヘッダーに移動、Home/Endで先頭/末尾。
- 初期状態/同時開閉ルール(1つのみ/複数可)を明記し、スクリーンリーダーにも伝わるようにする。
- 視覚的な三角アイコンなどに頼らず、テキストラベルを明確に書く。
使用法:
- 二次情報や詳細説明を段階的に開示したいときに使う。主要タスクの必須情報は最初から開いた状態にする。
- セクション見出しは意味を持つ短い文で命名し、内容の有無を推測できるようにする。
- ページ内ナビゲーションの代用にはしない(目次やサイドナビを検討)。
- 多段ネストは避け、1段まで。大量のアコーディオンは検索/フィルタを検討。
レイアウト:
- 見出しボタンは行全体をヒット領域にし、左右パディングは一貫(例: 12–16px)。
- 展開アイコン(例: シェブロン)は右端に揃え、テキストと十分な余白を取る。
- セクション間の間隔は8–16pxで統一。開閉でコンテンツが大きくジャンプしないようにする。
- コンテンツ領域は見出しより1段階インデントし、リスト/段落の余白もグローバルスケール(8px系)に合わせる。
- 長文はアコーディオンより別ページや詳細パネルを検討し、視線移動を最小化する。
色:
- 見出しテキストは本文と同等のコントラスト(4.5:1以上)。
- Hover/Pressedの背景は周囲と3:1以上の差。Focusリングは3:1以上で常に可視。
- 展開状態の強調は色だけに依存せず、アイコン回転/aria-expandedと文言で示す。
- 区切り線は低コントラストでも可だが、情報伝達はテキスト/構造で行う。
禁止事項:
- 重要な必須情報をアコーディオン内に隠す。
- 見出しをdivなどで疑似実装し、ボタン/キーボード操作/aria属性を欠落させる。
- アイコンだけで見出しを示す(テキストラベルなし)。
- 開閉時にフォーカスを不自然に移動させ、読書位置を失わせる。
ダイアログ
ガイドライン:
- 可能ならHTMLの<dialog>を使用。互換性上divの場合は role="dialog" と aria-modal="true" を設定。
- 見出しに id を付与し、aria-labelledby/aria-describedby でタイトルと説明を関連付ける。
- 開く際に適切な要素へ初期フォーカスを移動し、閉じるとトリガーへフォーカスを戻す(フォーカストラップ)。
- Escで閉じる、背景クリックの扱いは一貫させ、誤操作防止のために確認が必要な場合は明示する。
- バックドロップでは背景スクロールを抑止し、スクリーンリーダーが背景へフォーカスしないようにする。
使用法:
- フローを中断して意思決定を求めるときに限定して使う(確認、フォーム短タスク、重要な警告)。
- 軽微な説明やトーストで足りる情報には使わない。フォームの大部分はページ内で完結させる。
- アクションは右下に主要(Primary)/中立(Neutral)を配置し、一貫させる(例: Primary=実行、Neutral=キャンセル)。
- 破壊的操作は明確な文言(例: 削除)と確認文、代替手段の案内を伴わせる。
レイアウト:
- 画面中央に表示し、max-widthは用途に応じて約480–640px(フォームはやや広め可)。横幅はレスポンシブ。
- ヘッダー/本文/フッターを明確に区切り、内側パディングは16–24pxで統一。モバイルでは余白を増やす。
- 本文が長い場合は本文のみスクロールし、ヘッダー/フッターは固定。影や境界でレイヤーを示す。
- フッターのボタンは右寄せ(LTR)で並べ、ボタン間隔は8–12px。モバイルでは縦並びフル幅を検討。
- 背景はスクロール固定、背面のコンテンツ位置ズレを避ける(スクロールバー幅対策)。
色:
- サーフェス背景と本文テキストは4.5:1以上。見出しはさらに高コントラストを推奨。
- バックドロップは背景との差でレイヤーを示し、モーダル本体との区別も明確(影/境界+色)。
- 警告/危険(Danger)はセマンティックカラーを用い、色だけに依存せずアイコン/文言も併用。
- フォーカスリングは背景に対して3:1以上。ボタンの状態色(既定/ホバー/押下/無効)は一貫させる。
禁止事項:
- モーダルの多重表示や入れ子表示。
- フォーカストラップ不備(背景にフォーカスが戻る/閉じても呼び出し元に戻らない)。
- 閉じる操作が背景クリックのみで、キーボード/Escが効かない。
- タイトル/説明の関連付け(aria-labelledby/aria-describedby)欠如。
ボタン
ガイドライン:
- アクションはbutton、ナビゲーションはa(リンク)を使用して役割を分ける。
- ラベルは動詞+目的で簡潔に(例: 保存、送信)。アイコンのみの場合はaria-labelを付与。
- ローディング時はスピナーに加えてラベルを更新(例: 保存中…)。同一幅でレイアウトシフトを防ぐ。
- 無効化は disabled だけでなく、理由/代替手段をテキストで提供。必要に応じて aria-disabled を使い、フォーカス可否を設計意図に合わせる。
- キーボード/スクリーンリーダーで押下を認識できるよう、押下状態の視覚/音声フィードバックを用意。
使用法:
- 1画面につきPrimaryは原則1つ。その他のアクションはNeutralを使用する。
- 破壊的操作はDanger(セマンティック)を適用したPrimaryを使用し、誤押下を防ぐ間隔と確認を設ける。
- モバイルでは横幅を広く取り、縦並びで押しやすさを優先。
- 複数の関連アクションはボタングループやメニューにまとめ、視覚的優先度を整理する。
レイアウト:
- フォームではアクション群を末尾/右下に配置し、視線の流れに沿わせる。並び順は「Primary → Neutral」。
- ボタン間隔は8–12px、複数行回り込みは避け、溢れる場合はメニューに格納。
- アイコン付ボタンはラベルとの間隔を一定にし、高さは44px程度を目安(タッチ対象)。
- ツールバーではボタングループで整列し、関連操作を近接配置。
色:
- PrimaryとNeutralの2種に統一する。本文とのコントラストは4.5:1以上。
- 背景/境界/アイコンは状態(Hover/Pressed/Focus/Disabled)ごとに一貫した色を用意。UI要素は3:1以上。
- Danger(破壊的)はPrimaryのセマンティック変種として赤系を用い、文言でも危険性を明示する。
- テキストのみの中立ボタンはHover時に背景/境界で3:1以上の差を付け、押下可能性を示す。
禁止事項:
- divやspanでボタンを自作し、role/button動作/キーボードイベントを欠落させる。
- ナビゲーションにbuttonを使う(リンクはa要素を使用)。
- ページ内にPrimaryボタンを複数配置して優先度を曖昧にする。
- アイコンのみでラベルなし(aria-labelもなし)。
セレクトボックス
ガイドライン:
- 可能な限りネイティブ<select>を使用し、ラベル(label for)と関連付ける。
- オプションが多い場合はグルーピング(<optgroup>)や検索/フィルタの導入を検討。
- キーボード: Alt+↓で展開、↑↓で選択、Enter/Escで確定/閉じる等、プラットフォームの期待に沿う。
- エラー時はフィールド直下に説明を表示し、aria-invalid と aria-describedby を適切に設定。
使用法:
- 固定の選択肢から選ぶだけで十分な場合に最適。入力の自由度が不要で、選択肢が少数〜中程度。
- 初期値が必須でない場合は「選択してください」のダミー先頭項目を用意し、disabledで選べないようにする。
- 並び順はアルファベット/五十音/カテゴリで一貫させ、頻出項目を上位に配置してもよい。
- 選択肢が長大な場合はコンボボックスや検索を検討。
レイアウト:
- フィールド幅はフォームの他入力と揃え、最小幅を確保(例: 200px)。ラベルは上配置が基本。
- ドロップダウンの幅はトリガーと同等または内容に合わせて拡張、画面端では内側に折り返す。
- リストの最大高さを設定(例: 320px)し、スクロールを表示。各項目の行高は40–48px目安。
- エラーメッセージ/補助テキストは直下に配置し、余白は4–8px。
色:
- フィールドの枠/背景は既定/ホバー/フォーカス/無効/エラーの各状態で一貫した色を用意。
- プレースホルダーも読みやすいコントラスト(4.5:1以上)を確保し、ラベルの代替にしない。
- 選択中の行は背景/チェックアイコンで示し、色だけでなく太字/チェック記号で補強。行の背景差は3:1以上。
- エラー状態は境界/アイコン/説明テキストを赤系で統一し、説明文は4.5:1以上。
禁止事項:
- divで疑似セレクトを自作し、ネイティブのアクセシビリティ/モバイルピッカーを失う。
- placeholderでラベル代替、必須やエラーを色だけで示す。
- 数百件の選択肢をそのまま並べる(検索/カテゴリ分けなし)。
コンボボックス
ガイドライン:
- WAI-ARIAのComboboxパターンに従い、入力欄に aria-autocomplete(list/both)を設定。
- 候補リストは role="listbox"、各項目は role="option"、選択は aria-selected で示す。
- アクティブ項目は aria-activedescendant で関連付け、矢印キーで移動可能にする。
- 候補数や選択結果を aria-live="polite" で簡潔に通知し、過剰なアナウンスは避ける。
使用法:
- 選択肢が多い場合の検索/絞込、あるいは新規値の入力を許容するケースに用いる。
- 非同期取得では入力に対して遅延(デバウンス)を設け、結果数を簡潔に案内する。
- 自動補完は候補の強制選択を避け、ユーザーの自由入力を阻害しない。クリアボタンを提供する。
- モバイルでは候補の高さ/タップ領域を確保し、画面占有が大きい場合は専用画面への遷移も検討。
レイアウト:
- 入力欄はフォーム幅に合わせ、プレフィックス/サフィックスアイコンの内側余白を一定に。
- ドロップダウンは入力と同幅を基準に、画面端では内向きに調整。位置決めはビューポート内に収める。
- 候補リストは最大高さを設け(例: 320–480px)、多数項目では仮想スクロールを検討。
- 空状態/ロード中/エラーの行を用意し、内容が変化しても行高は安定させる。
色:
- 入力テキストは本文と同等のコントラスト(4.5:1以上)。一致ハイライトは色だけでなく強調(太字/下線)も併用。
- 候補のHover/選択背景は周囲と3:1以上。選択済みはチェック/アイコンで補強。
- クリア/展開アイコンは背景と3:1以上の差。無効時は控えめにしつつ、ラベルは可読性を保つ。
- ローディング/エラー行は色+アイコン+文言で伝え、色のみ依存を避ける。
禁止事項:
- 小規模候補にコンボボックスを使い過剰設計にする。
- ariaロール/属性(combobox, listbox, option, activedescendant等)を欠いた擬似実装。
- 入力ごとに過剰なライブリージョン通知や強制選択でユーザー制御を奪う。
- キーイベントを過度に奪取し、標準のテキスト編集操作を阻害する。
セレクトボックスとコンボボックスの違い
定義:
- セレクトボックス: ネイティブの<select>を用いて、あらかじめ定義された選択肢から選ぶ。自由入力は不可。単一選択が基本(multiple属性で複数選択可)。
- コンボボックス: 入力欄+候補リストの複合コントロール。検索/絞り込みや自由入力が可能。WAI-ARIAのComboboxパターンで実装。
使い分けの目安:
- 選択肢が少数(おおむね10〜20件)で固定、自由入力不要 → セレクトボックス。
- 選択肢が多数(20件超)で検索・絞り込みが必要、または新規値の入力を許容 → コンボボックス。
アクセシビリティの観点:
- セレクトボックス: ブラウザ/OSが提供する既定の読み上げ・キーボード操作が最も堅牢。可能な限り優先。
- コンボボックス: role="combobox"、aria-expanded、aria-controls、aria-autocomplete、listbox/option、aria-activedescendant などを正しく実装しないと利用困難になりやすい。
キーボード操作(概要):
- セレクトボックス: Tabでフォーカス、Alt+↓で展開、↑↓で移動、Enter/Escで確定/閉じる、タイプアヘッドで項目ジャンプ。
- コンボボックス: Tabで入力へ、文字入力でフィルタ、↓で候補展開、↑↓で移動、Enterで確定、Escで閉/入力クリア、Home/Endで先頭/末尾。
スクリーンリーダーの期待:
- セレクトボックス: ラベルと現在値が読み上げられ、プラットフォームの既定に準拠(環境により「コンボボックス」と表現される場合あり)。
- コンボボックス: 役割=combobox、候補数、選択状態、展開/折りたたみの有無を簡潔に案内。過剰なaria-liveは避ける。
モバイル特性:
- セレクトボックス: OSのピッカーUIを使用でき、操作が容易。
- コンボボックス: 画面が狭くなるため候補の高さ・スクロール・タップ領域(約44px)を確保。
性能/実装コスト:
- セレクトボックス: 実装容易で堅牢だが、見た目のカスタマイズに制約。
- コンボボックス: 柔軟だが実装/保守コストが高い。仮想化や非同期取得時のARIA整合が重要。
アンチパターン:
- 選択肢が少ないのにコンボボックスを用いる。
- セレクトボックスをdivなどで再実装し、ネイティブのアクセシビリティを失う。
- 色やアイコンのみで選択状態を示す(テキスト/属性でも状態を示す)。
最低限の要件:
- セレクトボックス: label/for で関連付け、エラー時は aria-invalid と説明(aria-describedby)を併用。
- コンボボックス: 明確なラベル、適切なrole/aria属性、フォーカス管理、確定/キャンセル動作の一貫性、キーボード操作の完備。
ラジオボタン
ガイドライン:
- 相互排他の選択には<input type="radio">を使用し、fieldset + legend でグルーピングと見出しを提供。
- 1つは初期選択しておく(未選択が妥当な要件なら、その理由とデフォルト動作を明示)。
- キーボード: Tabでグループへ、矢印キーで選択を移動。
使用法:
- 2〜7件程度の相互排他選択に適する。選択結果が送信時に反映される設定向け。
- Yes/Noの即時適用はスイッチ、送信時確定ならラジオを選ぶ。
- 各選択肢は意味が排他的で、重複しない文言にする。必要に応じて「該当なし」を用意。
レイアウト:
- ラベルが短い/項目が少数なら横並び、長文/多数なら縦並び。1行は2–3項目までを目安。
- 項目間隔は8–16px、グループ外側の余白は上下16–24px。legendはグループの見出しとして上部に。
- ラジオの丸印はラベル1行目のベースラインに揃え、複数行折返しでも見やすく配置。
色:
- 選択ドットと外枠は背景と3:1以上。ラベルは本文基準(4.5:1以上)。
- Hover/Focus/Disabledの各状態で一貫した色。Focusリングは3:1以上。
- エラー時はグループ見出し/補助文を赤系で統一し、色だけでなくテキストでも問題を伝える。
禁止事項:
- 複数選択が必要な場面でラジオボタンを使用。
- fieldset/legendでのグルーピングを省略して文脈を失わせる。
- すべて未選択のまま送信必須にし、エラー案内を出さない。
チェックボックスとスイッチ
ガイドライン:
- チェックボックス: 独立した真偽や複数選択向け。スイッチ: 即時適用されるオン/オフ設定向け。
- ラベルは常に可視で、状態を文面でも示す(例: 通知: オン)。
- グループにはfieldset + legendを使用し、関連する説明は aria-describedby で関連付ける。
使用法:
- チェックボックス: 同意や複数条件の選択、リストの一括選択(不定状態含む)。
- スイッチ: 画面に即時反映される設定のトグル。遅延がある処理はスピナー/トーストで結果を知らせる。
- 破壊的/不可逆な操作にはスイッチを使わない。
レイアウト:
- チェックボックス群は縦積みを基本に、項目間隔8–12px。ラベルは右に置き、行全体をヒット領域に。
- 一括選択は親チェックボックスをヘッダーやリスト先頭に配置し、子との距離を明確に取る。
- スイッチは行末配置が分かりやすいが、ラベルとの距離を一定に。行高は44px程度を目安。
- 追補説明は次行に小さめのテキストで配置し、左右位置を揃える。
色:
- チェック(✔)またはインデターミネイト(—)は背景と3:1以上の差。ラベルは4.5:1以上。
- スイッチのオン/オフトラックとサムは状態が判別できる配色で、色だけに依存しない(テキスト/状態表示を併用)。
- Disabledは控えめな配色にするが、ラベルの可読性は維持。
- Focusリングは3:1以上。エラー時は赤系を用い、補助文を併記。
禁止事項:
- 重要な破壊的操作や長時間処理をスイッチで即時適用。
- 三状態(不定)を説明なく使い、意味を曖昧にする。
- チェックボックスのラベルを非表示にし、アイコンや色のみで意味を伝える。
テキストボックス
ガイドライン:
- label と input を for/id で関連付け、placeholder をラベルの代替にしない。
- 必須は「必須」などのテキストで示し、色のみで伝えない。エラーはフィールド直下に配置し、aria-invalid と aria-describedby を設定。
- 入力支援: type/email/url/number、autocomplete 属性、入力例は補助テキストとして提供。
- リアルタイム検証は控えめにし、フォーカスアウトや送信時に明確なメッセージを返す。
使用法:
- 単一行は短い入力、複数行(textarea)は説明やコメントなど長文向け。
- 文字数/形式制限がある場合は事前にガイダンスを表示し、残り文字数はaria-describedbyで関連付ける。
- マスク(電話/カード)では入力中の可読性を優先し、表示/非表示トグルを用意(パスワード等)。
- IME入力と検証の競合を避け、composition中はエラー表示を抑制する。
レイアウト:
- ラベルは上配置が基本。フォーム全体で幅を揃え、入力欄は可能な限りフル幅に。
- 補助テキスト/エラーは直下に配置し、上下4–8pxの余白を確保。複数要素の順序は「ラベル→入力→補助→エラー」。
- 複数カラムのフォームではブレークポイントで1カラムに落とし、読み順を維持。
- プレフィックス/サフィックス(アイコン/単位)は内側余白を統一し、クリック可能領域を確保。
色:
- ボーダー/背景は既定/ホバー/フォーカス/無効/エラー/成功の各状態で一貫した色。フォーカスは3:1以上。
- プレースホルダー/補助テキスト/エラーテキストはいずれも4.5:1以上のコントラストを確保。
- 必須アスタリスクは色強調してもよいが、必ず「必須」テキストを併記(色のみ禁止)。
- 無効化は低コントラストにしつつ、入力内容が読み取れる程度は維持する。
禁止事項:
- placeholderをラベルの代替にする。
- 入力のたびに警告を読み上げ続ける(ライブリージョンの氾濫)。
- オートコンプリートを意図なく無効化し、ユーザーの支援を奪う。
- フォーカスリングをCSSで消す。
データグリッド
ガイドライン:
- 単なる表は<table>を用い、<th>にscope(col/row)を付与。全体の説明は<caption>で提供。
- ソート可能列は aria-sort を使用し、キーボード操作で切替可能にする(Enter/Space)。
- 行選択などインタラクティブなグリッドは role="grid" を検討し、セル/行へのフォーカス移動(矢印キー)を提供。
- 水平/垂直スクロールでは、可視領域外にフォーカスが逃げないようにし、見出しを固定するなどで文脈を保つ。
- ページネーションや件数変更はフォームコントロールで提供し、更新結果は aria-live で簡潔に通知。
使用法:
- 多列・多数行のデータ表示/比較/操作に用いる。単純一覧ならリスト/カードの方が適切な場合が多い。
- 基本操作(ソート/フィルタ/ページネーション/列表示切替)は一貫した位置に集約し、現在の適用状態を明示する。
- 行内編集は保存/取消の明確な動線を用意し、一括編集が必要なら別画面やダイアログを検討。
- 大量データは仮想化/遅延読み込みを併用し、フォーカス移動や読み上げに配慮する。
レイアウト:
- ヘッダーは固定(sticky)にし、縦スクロール時に列の意味を保持。行高は40–48pxを目安に統一。
- 列はmin/max幅を設定し、重要列を優先表示。狭い画面では列の非表示/折りたたみ/カード表示を検討。
- 操作用の列(アクション)は右端にまとめ、間隔を一定に。選択チェックは左端に配置。
- ページネーション/件数切替/合計件数は下部右寄せ(LTR)でまとめ、並びを一貫させる。
色:
- ヘッダーと本文行の背景差は控えめにしつつ可読性を確保。テキストは4.5:1以上。
- Hover/選択行/フォーカスセルは背景/境界で示し、周囲と3:1以上の差。選択はチェックやアイコンで補強。
- ソート中の列はアイコン/テキストで状態を示し、色のみ依存にしない。
- リンク/エラー/成功の状態色はセマンティックに統一し、説明テキストと併用。
禁止事項:
- table/gridのセマンティクスを持たないレイアウトで表を自作。
- 見出し<th>やscope属性の欠落、列の意味が不明瞭。
- 無限スクロールでフォーカスや読み上げの位置を見失わせる(ページネーション不備)。
- ソート/フィルタをアイコンや色のみで表現し、テキストと属性を欠く。
テストと検証
短時間でのセルフチェック:
- キーボードのみで主要フローを完遂できる(Tab/Shift+Tab/Enter/Space/矢印/Esc)。
- フォーカスが常に見える。タブ順が論理順である。
- コントラストが基準を満たす(本文4.5:1以上、大きな文字3:1以上、UI 3:1以上)。
- 200%/400%ズームでも情報が欠落せず、横スクロールが最小限で済む。
- prefers-reduced-motion で動きが抑制され、内容理解に支障がない。
- 主要スクリーンリーダー(NVDA/Windows Narrator等)で、ラベル・役割・状態・値が読まれる。
参考リンク:
- Fluent 2 Design System: https://fluent2.microsoft.design/
- Microsoft Inclusive Design: https://inclusive.microsoft.design/
- WCAG 2.2(日本語訳): https://waic.jp/docs/WCAG22/
Discussion