Skip to content

テクニック H102:HTMLdialog 要素を用いてモーダルダイアログを作成する

このテクニックについて

このテクニックは 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 要素が含まれており、アクティブ化されるとモーダルダイアログが呼び出される。この buttontype 属性を使用して、ブラウザに 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">&times;</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);

});

関連リソース

推奨を意味するものではない。

検証

手順

  1. ページ上で、モーダル dialog 要素を呼び出すコンポーネントを見つける。
  2. dialog が、キーボードを使用して呼び出し元の要素をアクティブ化することで開くことができることをチェックする (例えば、Enter キー、又は Spacebar を押すことで button をアクティブ化する)。
  3. モーダル dialog が開いているとき、フォーカスがそのダイアログ又はそのフォーカス可能な子孫のいずれかに移動していることをチェックする。
  4. モーダル dialog が開いている間は、キーボードフォーカスが主要なドキュメントの要素に移動できないことをチェックする。
  5. モーダル dialog が閉じられたとき、呼び出し元の要素がページ上にまだ存在する場合、フォーカスがその要素に戻っていることをチェックする。

期待される結果

  • チェック 2、3、4 及び 5 が真である。
Back to Top