モーダル
component大事な確認や入力をお願いするとき、画面の最前面に重ねて表示する小さなウィンドウです。閉じるまで後ろの画面は操作できません。
構成
ヘッダ(タイトル + 閉じるボタン)/ ボディ / フッタ(アクション右寄せ)。寸法・配色はカードと共通。下は開いた状態の静的プレビュー(.is-static-preview)
使用例 — 実際に開いてみる
data-modal-open="ID" のボタンで開き、data-modal-close / Esc キー / 背景クリックで閉じる
機能
このコンポーネントの用途
確認や入力を求めるとき最前面に重ねるダイアログ。ネイティブ <dialog> ベース。
ページ内に常設で知らせるだけなら modal ではなく alert。
使用法
推奨される使い方と、やりがちな NG パターン
OK
- ✓showModal() で開き、フォーカス管理と Esc 閉じはブラウザ標準に任せる。
- ✓aria-labelledby でタイトルと関連付ける。
NG
- ✕情報表示だけに多用しない → 操作を止める必要がある時に限る。
- ✕閉じる手段(閉じるボタン / Esc)を消さない。
破壊的操作の確認は主アクションを negative に
確認ダイアログ
削除など不可逆な操作の主ボタンは negative。取り消せないことを本文で明示する。
削除の主ボタンを primary(肯定色)にしない。危険な操作だと色で伝わらない。
モーダルのアクセシビリティ
ネイティブ <dialog> + showModal() により、フォーカストラップ・背景の不活性化・Esc 閉じが標準で得られます。タイトルの関連付けとフォーカス復帰はプロダクト側で担保します。WCAG 2.2 全基準は アクセシビリティ ページを参照。
期待される配慮
Presentation / Adaptability / Interaction / Assistive Technology
背景を暗くして最前面に集中させる。タイトルと閉じるボタンを明示し、主アクションの色で意味を伝える。
幅は上限付きで可変、内容が長ければスクロール。文字は rem で拡大に追従。
開くとフォーカスが内部へ移り、Tab はモーダル内で循環(トラップ)。Esc と背景クリックで閉じ、フォーカスは開いた要素に戻る。
ネイティブ <dialog> により role="dialog"・aria-modal が付き、背景は不活性。aria-labelledby でタイトルを名前にする。
DS が担保する機能
追加実装なしで満たされる
- ✓ネイティブ
<dialog>+showModal()— フォーカストラップ・背景の不活性化・Esc閉じが標準 - ✓
::backdropで背景を暗くし、閉じたときフォーカスが呼び出し元へ戻る(<dialog>の標準挙動) - ✓カタログ JS で背景クリック・
data-modal-closeによる閉じを提供
実装時の必須対応
プロダクト側で担保する
- !
<dialog aria-labelledby>でモーダルタイトル(modal-titleのid)を名前にする - !開くときは
showModal()を使う(open属性の直書き/show()はトラップ・不活性化が効かない) - !閉じるボタンに
aria-label="閉じる"。閉じた後フォーカスを呼び出し元に戻す - !不可逆な操作は本文で明示し、主アクションを
negativeに
テスト方法
キーボード / スクリーンリーダー / 自動チェック
| キー | 動作 |
|---|---|
| Tab / Shift+Tab | モーダル内だけを循環(背景に出ない) |
| Esc | モーダルを閉じ、フォーカスが呼び出し元へ戻る |
- SR開くと「ダイアログ、(タイトル)」と読まれ、背景のコンテンツは読み上げ対象外になる
- 操作背景クリック・閉じるボタンでも閉じられ、フォーカスが戻る
- 自動axe / Lighthouse で
aria-labelledby・閉じるボタン名・コントラストを確認
タイトルを aria-labelledby で関連付け
達成基準:WCAG 4.1.2 名前・役割・値
aria-labelledby がタイトル id を指し、閉じるは aria-label。
<dialog class="modal" aria-labelledby="title"> <h2 class="modal-title" id="title">プロフィールの編集</h2> <button class="icon-btn …" aria-label="閉じる">×</button> </dialog>
aria-labelledby が無いとダイアログに名前が付かず、閉じるボタンも「ボタン」としか読まれない。
<dialog class="modal"> <!-- aria-labelledby なし --> <h2 class="modal-title">プロフィールの編集</h2> <button class="icon-btn …">×</button> <!-- aria-label なし --> </dialog>