テクニック H102:HTML の dialog
要素を用いてモーダルダイアログを作成する
このテクニックについて
このテクニックは 2.4.3: フォーカス順序 に関連する。 (ウェブページを動的に変更するために使用される場合、十分なテクニック)
このテクニックは HTML に適用される。
解説
ウェブサイト制作者は、主要ページのコンテンツの範囲を超えた情報又はタスク関連のアクティビティに利用者の注意を向けさせるために、モーダルダイアログをよく使用する。モーダルダイアログは、ARIA dialog ロール及び関連属性、又は HTML dialog
要素を用いたマークアップで構築できる。ARIA の第 1 ルールを満たすだけでなく、HTML dialog
要素は、ブラウザがこれらの機能を処理することで、ARIA に比べていくつかの利点を提供する:
- キーボードフォーカスは新しく開いたモーダル
dialog
に移動する。 - モーダル
dialog
が閉じられると、キーボードフォーカスは呼び出し元の要素に戻る (その要素がまだページ上にあるなら)。 - キーボードフォーカスは、モーダル
dialog
のコンテンツとブラウザのクロム (アドレスバーなどのブラウザ固有の UI) に限定される。 - モーダルダイアログの「外側」にあるページコンテンツは inert になり、その結果、モーダル
dialog
が開いている限り、コンテンツは支援技術から非表示になり、すべての利用者が操作できなくなる。 - Escape キーを使用するとモーダル
dialog
が閉じる。
このテクニックでは、カスタム ARIA 実装ではなく HTML dialog 要素を使用するため、アクセシブルなモーダル dialog
を作成するための労力が軽減される。
事例
事例 1: メーリングリストへの登録ダイアログ
これは、モーダル dialog
要素を使用して、利用者にメーリングリスト登録フォームを表示する例である。ページの主要部分には、button
要素が含まれており、アクティブ化されるとモーダルダイアログが呼び出される。この button
は type
属性を使用して、ブラウザに submit
button
ではないことを伝えている。
モーダル dialog
が開かれると、ブラウザはモーダルダイアログの外側にあるすべてのコンテンツを不活性なものとして扱い、操作不能にし、支援技術からコンテンツを隠す。例えば、スクリーンリーダーは不活性なコンテンツにアクセスしたり、読み上げたりすることができない。さらに、ページコンテンツが不活性であるため、キーボードフォーカスは dialog
要素内のフォーカス可能な要素とブラウザのコントロールにのみアクセスできる。ダイアログが呼び出されると、ブラウザはダイアログの DOM 内で最初のフォーカス可能な要素に自動的にフォーカスを設定する。この例では、tabindex="-1"
属性を持つ h1
要素がフォーカスを受け取る。dialog
の閉じるボタンは h1
要素の前に表示されているものの、ダイアログの DOM 内では最後の要素であることに注意する。もしもこの button
が先頭にあったならば、ダイアログが開かれたときにフォーカスが当たってしまうだろう。
HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1, shrink-to-fit=no">
<title>Turbo Encabulator News</title>
</head>
<body>
<main>
<h1>All The News About Turbo Encabulators</h1>
<button class="open-modal" type="button">Sign up to our mailing list!</button>
</main>
<dialog aria-labelledby="dialog-heading" id="mailing-list-dialog">
<h1 id="dialog-heading" tabindex="-1">Sign up to our mailing list</h1>
<form>
<p class="req-note">All form fields are required.</p>
<div>
<label for="fname">First Name</label>
<input aria-required="true" autocomplete="given-name" id="fname" type="text">
</div>
<div>
<label for="lname">Last Name</label>
<input aria-required="true" autocomplete="family-name" id="lname" type="text">
</div>
<div>
<label for="email">Email address</label>
<input aria-required="true" autocomplete="email" id="email" type="text">
</div>
<button class="sign-up" type="submit">Sign up</button>
</form>
<form method="dialog">
<button aria-label="close" class="close-modal">×</button>
</form>
</dialog>
</body>
</html>
CSS
*, *::after, *::before {
box-sizing: inherit;
}
body {
background:#fff;
color:#000;
font:1rem/1.5 system-ui, Helvetica, Roboto, sans-serif;
}
*:focus-visible {
outline:1px solid #0054AE;
outline-offset:1px;
}
dialog {
border:1px solid #000;
padding:2rem;
position:relative;
}
dialog::backdrop {
background-color:hsla(0, 0%, 0%, .5);
}
.close-modal {
inset-block-start:1.5rem;
inset-inline-end:1.5rem;
line-height:1.3;
padding:0.25em 0.5em;
position:absolute;
}
.sign-up {
background:#000;
color:#fff;
padding:0.25em;
}
dialog h1 {
display:inline-block;
line-height:1.3333;
margin:0;
max-inline-size:95%;
}
form {
display:grid;
grid-gap:20px;
grid-template-columns:repeat(auto-fit, minmax(150px, 1fr));
}
.req-note, .sign-up {
grid-column:1 / -1;
}
label {
display:block;
}
input {
border:1px solid hsl(0, 0%, 50%);
font:inherit;
inline-size:calc(100% - 4px);
}
button {
background:#fff;
border:1px solid hsl(0, 0%, 50%);
border-radius:3px;
color:inherit;
font:inherit;
margin:0;
}
JavaScript
スクリプトは、呼び出されたときに dialog
を表示するために必要である。HTML dialog
要素は、二つの異なるコマンドを使用して開くことができる: show()
コマンド(非モーダル dialog
の場合)及び、この例で使用されている showModal()
コマンド(モーダル dialog
の場合)。
注記: dialog
を閉じる関数を記述する代わりに、閉じるボタンを method="dialog"
属性を持つ別の form
要素内にネストしている。この方法により、このボタンが押されたときにダイアログが閉じられ、ブラウザは呼び出し元の要素にキーボードフォーカスを戻す処理を行う。
document.addEventListener("DOMContentLoaded", function(e){
const d = document.querySelector("dialog");
const btnOpen = document.querySelector(".open-modal");
btnOpen.addEventListener("click", function(){
d.showModal();
}, false);
});
関連リソース
推奨を意味するものではない。
検証
手順
- ページ上で、モーダル
dialog
要素を呼び出すコンポーネントを見つける。 - 各
dialog
が、キーボードを使用して呼び出し元の要素をアクティブ化することで開くことができることをチェックする (例えば、Enter キー、又は Spacebar を押すことでbutton
をアクティブ化する)。 - モーダル
dialog
が開いているとき、フォーカスがそのダイアログ又はそのフォーカス可能な子孫のいずれかに移動していることをチェックする。 - モーダル
dialog
が開いている間は、キーボードフォーカスが主要なドキュメントの要素に移動できないことをチェックする。 - モーダル
dialog
が閉じられたとき、呼び出し元の要素がページ上にまだ存在する場合、フォーカスがその要素に戻っていることをチェックする。
期待される結果
- チェック 2、3、4 及び 5 が真である。