以下では、DOM を用いてアクセシブルな「モーダルウィンドウ(オーバーレイダイアログ)」を実装する方法を、設計要件 → 最小実装(HTML/CSS/JS) → 動作の要点 → ベストプラクティスと拡張、の順で詳しく解説します。説明文中に絵文字は使用しません。
1. モーダルの目的と必須要件
モーダルは、ユーザーの注意を一時的に一点に集め、同時に背後のコンテンツ操作を停止させる UI です。実装上の必須事項は次のとおりです。
-
背景の操作とフォーカス移動を遮断(フォーカストラップ)
-
Esc キーや閉じるボタンで確実に閉じられる
-
開いたらモーダル内の適切な要素へ初期フォーカス、閉じたら元のフォーカスを復帰
-
スクリーンリーダー向けに
role="dialog"/aria-modal="true"、aria-labelledby/aria-describedbyを付与 -
背景スクロールをロック(必要に応じてスクロールバー幅の補正)
2. 最小実装(アクセスビリティ対応)
2.1 HTML
2.2 CSS(レイアウトとトランジション)
2.3 JavaScript(開閉・フォーカストラップ・Esc・背景ロック)
3. DOM 操作のポイント解説
-
表示/非表示は hidden 属性で制御し、CSS の display: none として機能させています。視覚・スクリーンリーダー双方で確実に非表示になります。
-
フォーカストラップ:keydown の Tab をフックし、モーダル内のフォーカス可能要素を列挙して先頭↔末尾で循環させています。
-
初期フォーカス/復帰:開く前の document.activeElement を保存し、閉じたら戻します。開いた直後は確実に操作可能なボタン等へフォーカスします。
-
背景無効化:inert が使える環境では pageRoot.inert = true で背後のフォーカス移動とクリックを抑止します。非対応環境向けに aria-hidden を併用しています。
-
Esc/オーバーレイクリック:閉じる経路を複数用意します。role=”dialog” かつ aria-modal=”true” でスクリーンリーダーにモーダル状態を通知します。
-
スクロールロック:body { overflow: hidden }。スクロールバー消失で横幅がずれる場合は、消失分の幅を padding-right に加算してレイアウトシフトを抑えています。
4. アクセシビリティの要点チェックリスト
-
role=”dialog”, aria-modal=”true”
-
aria-labelledby(見出し要素の id を参照)と aria-describedby(説明要素の id)
-
初期フォーカスを設定し、Tab でモーダル内を循環
-
Esc で閉じられる
-
背景コンテンツはフォーカス不可(inert、なければ aria-hidden)
-
閉じたら元のフォーカスへ復帰
5. よくある拡張・発展
-
アニメーション
開閉時に is-open クラスをトグルし、CSS の opacity / transform、transition で柔らかく表示。閉じるときは transitionend を待ってから hidden を付与。 -
複数モーダル
data-open-modal=”#id” の仕組みで任意のモーダルを開けます。スタック(入れ子)を許可する場合は、背後のモーダルに aria-hidden を付与し、フォーカスマネジメントを一段上書きする必要があります。基本は入れ子を避ける設計が無難です。 -
閉じた理由の把握
保存/キャンセル/オーバーレイクリック/Esc など、原因ごとにハンドラで分岐してイベントを発火させると、呼び出し側で振る舞いを切り替えられます。 -
動的な内容差し替え
innerHTML で差し込む場合は信頼できるコンテンツのみに限定し、ユーザー入力はエスケープして XSS を防止します。理想的には DOM API(createElement 等)で要素を構築します。 -
フォーム内スクロール
モーダル内容が長い場合は .modal__window { max-height: 90vh; overflow: auto; } を付与すると、背景を固定したまま内部のみスクロールできます。
6. 別解:ネイティブ <dialog> 要素で作る最小例
モダンブラウザでは <dialog> の showModal()/close() が使えます。フォーカストラップや背景ロックが組み込みで扱いやすく、簡素です。
<dialog> は簡潔ですが、ブラウザ実装差異や既存の CSS レイアウトとの整合が必要になる場合があります。細かな制御が必要なら前節のカスタム実装が柔軟です。
7. まとめ(実装の指針)
-
まずは アクセシビリティ要件(ロール、初期フォーカス、Esc、フォーカストラップ、背景無効化)を満たす。
-
視覚表現は オーバーレイ + ウィンドウ の二層構造にし、アニメーションはクラス切り替えで制御。
-
スクロールロックとフォーカス復帰で、開閉時の違和感を最小化。
-
拡張は後付け可能な設計(閉じる理由の通知、バリデーション、ボタンのローディング状態など)にする。
この流れに沿って実装すれば、実運用で問題が起きにくい堅牢なモーダルを DOM だけで構築できます。
ChatGPT5 生成日:2025/09/11