モーダルを開いても背後にフォーカスが残る
ダイアログが表示されても、Tabキーで移動する先は背後のページです。
問題
ダイアログは表示されているのに、キーボード操作は背後のページに残っています。
場面 Tabキーで、背後のページを移動してしまう。 詳しく読む閉じる
詳細編集のダイアログを開くと、ページの上に重なって表示されます。しかしTabキーを押すと、ダイアログ内ではなく、背後のリンクへフォーカスが移動します。
確認できる問題 見た目はモーダルでも、動作が伴っていない。 詳しく読む閉じる
見た目はモーダルでも、フォーカスの移動が適切に管理されていません。背後のページを操作できてしまい、ダイアログが開いたことに気づけない場合があります。
利用者への影響 キーボードやスクリーンリーダーの利用者が、別の場所を操作してしまう。 詳しく読む閉じる
キーボードやスクリーンリーダーの利用者が、ダイアログの外を操作してしまったり、必要な入力に気づけなかったりします。閉じた後も、操作を再開する位置が分からなくなるおそれがあります。
自動チェックとAIの限界 roleやaria-modalだけでは、フォーカスは移動しない。 詳しく読む閉じる
role と aria-modal を設定するだけでは、フォーカスは移動せず、背後のページの操作も防げません。初期状態のDOMだけでは、開閉時、ダイアログ内の移動、閉じた後のフォーカスが適切か判断できません。
試してみる
ダイアログを開いてから、Tabを押してください。
ダイアログを開き、TabキーとEscapeキーを押してください。
再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。
修正方法
HTML標準のdialogをshowModal()で開き、閉じた後のフォーカス位置を確認します。
- 1
aria-labelledbyでダイアログに名前を付ける。 - 2最初のフォーカスは作業の起点か、最も影響の小さい操作に置く。
- 3閉じたら開いたボタンへ、ない場合は適切な位置へフォーカスを戻す。
html
<div class="overlay" hidden> <div class="modal"> <p class="modal-title">詳細を編集</p> <button onclick="closeModal()">閉じる</button> </div></div>js
function openModal() { document.querySelector('.overlay').hidden = false;}html
<button type="button" id="edit-trigger">詳細を編集</button> <dialog id="edit-dialog" aria-labelledby="edit-title"> <h2 id="edit-title">詳細を編集</h2> <form method="dialog"> <label for="display-name">表示名</label> <input id="display-name" name="name"> <button value="save">保存</button> <button value="cancel">キャンセル</button> </form></dialog>js
const trigger = document.getElementById('edit-trigger');const dialog = document.getElementById('edit-dialog');trigger.addEventListener('click', () => dialog.showModal());js
// 閉じた後に開くボタンが残っていない場合は、移動先を決めます。dialog.addEventListener('close', () => { if (!trigger.isConnected) document.getElementById('item-list')?.focus();});この修正で直る理由
オーバーレイを表示しても、変わるのは見た目だけです。フォーカスは開くボタンに残り、Tabキーは背後のページを移動し、Escapeキーも効かず、ダイアログには名前もありません。
showModal() は、ダイアログ内へフォーカスを移し、背後のページを操作できない状態にし、Escapeキーで閉じられるようにします。method="dialog" のフォーム内のボタンでも閉じます。現在のブラウザーは、閉じた後に開いた要素へフォーカスを戻しますが、画面の再描画でその要素が置き換わることもあるため、必ず確認してください。
実装の判断
長いダイアログは、tabindex="-1" の見出しを初期位置にする場合があります。削除など取り消せない操作では、キャンセルなど安全な選択肢に最初のフォーカスを置き、そのボタンに autofocus を指定します。ダイアログを入れ子にする場合は、閉じた後のフォーカス移動も確認してください。
dialog要素を使えない場合も、独自のモーダルで同じ動作が必要です。role="dialog" と aria-modal="true" と名前を設定し、開いたらフォーカスを移し、背後のページを inert にし、Escapeキーで閉じ、閉じたらフォーカスを戻します。
修正の確認
マウスを使わない5つの確認
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通のダイアログコンポーネントを変更した際は、再度確認します。
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。保存や入力検証の処理は省略しています。実際に使用する支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
参考資料: www.w3.org
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。