dialog要素でダイアログボックスやモーダルウィンドウを実装
2023年 5月17日 Posted 野々瀨(フロントエンドエンジニア)
ダイアログボックスやモーダルウィンドウはさまざまなところで実装され活躍しています。簡単なダイアログボックスであれば、JavaScriptのwindow.alertメソッドやwindow.promptメソッドで実装することができます。複雑な実装するうえでは独自で開発する必要があり、アクセシブルなダイアログボックスやモーダルウィンドウを実装するのはなかなかに困難です。
そんなアクセシブルなダイアログボックスやモーダルウィンドウは、dialog要素で実装することができます。ここではそんなdialog要素で、ダイアログボックスやモーダルウィンドウを実装する方法をご紹介します。
dialog要素とは
dialog要素は、HTML 5.2で登場し、HTMLの標準でダイアログボックスやモーダルウィンドウを実装することができます。最上位レイヤーで表示されますので、CSSのz-indexプロパティによるレイヤーレベルを気にする必要がありません。
dialog要素には、JavaScriptのwindow.alertメソッドのような、ウィンドウを閉じたりするボタンは実装されていません。しかし、JavaScriptで簡単に実装することはできます(後ほどご紹介します)。
dialog要素の特長
特長としては主に次の通りです。
- 最上位レイヤーで表示される(z-indexプロパティを気にする必要がない)
- 開くや閉じるなど実装が容易に行える
- スタイルもシンプルにあてることができる
- フォーカスの移動やEscキーによる閉じるなどアクセシビリティに配慮されている
関連リンク
対応ブラウザー
IEを除く最新バージョンでは、ほぼ全てのブラウザーで対応しています。
| ブラウザー | 対応バージョン |
|---|---|
| IE | 未対応 |
| Edge | 79+ |
| Chrome | 37+ |
| Firefox | 98+ |
| Safari | 15.4+ |
| Opera | 24+ |
| Chrome for Android | 37+ |
| iOS Safari | 15.4+ |
簡単な実装方法
まずdialog要素を記述し、表示したい中身をdialog要素の中に記述します。開くためのbutton要素とdialog要素内には閉じるための要素を記述します。
<button type="button" class="open-modal">開く</button>
<dialog class="modal">
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit.<br>
Quo rem debitis in, voluptatem sequi vel earum deserunt labore.<br>
Nihil facilis aliquam inventore amet itaque ducimus, quisquam ratione quis cum harum.</p>
<button type="button" class="close-modal">閉じる</button>
</dialog>
開く処理と閉じる処理のJavaScriptを記述します。開くときはHTMLDialogElement.showModalメソッド、閉じるときはHTMLDialogElement.closeメソッドを使用します。
const dialogElem = document.querySelector('.modal'); // dialog要素
const openBtnElem = document.querySelector('.open-modal'); // 開くボタン要素
const closeBtnElem = dialogElem.querySelector('.close-modal'); // 閉じるボタン要素
// 開くボタンを押した時
openBtnElem.addEventListener('click', () => {
dialogElem.showModal(); // dialogを開く(表示)
});
// 閉じるボタンを押した時
closeBtnElem.addEventListener('click', () => {
dialogElem.close(); // dialogを閉じる(非表示)
});

関連リンク
イベント
dialog要素が閉じられた時を得たい場合は、closeイベントを使用します。また、dialog要素がEscキーでキャンセルした時を得たい場合は、cancelイベントを使用します。
なお、Escキーを押した時は、closeイベントとcancelイベントの両方が発火します。
※ 残念ながら開いた時のイベントはありません。
const dialogElem = document.querySelector('.modal');
// 閉じた時
dialogElem.addEventListener('close', () => {
alert('閉じました');
});
// キャンセルした時
dialogElem.addEventListener('cancel', () => {
alert('キャンセルされました');
});

また、HTMLDialogElement.closeメソッドの引数を指定しますと、cancelイベントでevent.target.returnValueプロパティから、引数の値を得ることができます。
const dialogElem = document.querySelector('.modal');
const closeBtnElem = dialogElem.querySelector('.close-modal');
// 閉じた時
dialogElem.addEventListener('close', event => {
alert(event.target.returnValue); // closeメソッドからの引数の値を得る
});
// 閉じるボタンを押した時
closeBtnElem.addEventListener('click', () => {
dialogElem.close('abc'); // closeイベントに渡す値を指定
});

関連リンク
オーバーレイ
オーバーレイはCSSの::backdrop疑似要素を使用して表現します。
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.8);
}
関連リンク
開かれた時のスタイル
開かれた時のみスタイルをあてるには、:modal疑似クラスを使用します。これはHTMLDialogElement.showModalメソッドで開かれた場合でのみ適用されます。
dialog:modal {
border: 5px solid #999;
border-radius: 10px;
padding: 10px;
}
なお、:modal疑似クラスは対応ブラウザーがdialog要素より後ですので、ご注意ください。
| ブラウザー | 対応バージョン |
|---|---|
| Edge | 105+ |
| Chrome | 105+ |
| Firefox | 103+ |
| Safari | 15.6+ |
| Opera | 91+ |
| Chrome for Android | 105+ |
| iOS Safari | 15.6+ |
関連リンク
開いたかどうかを得る
dialog要素が開かれたかどうかをHTMLDialogElement.openプロパティで得ることができます。開いていればtrueを得ることができ、閉じていればfalseを得ることができます。
const dialogElem = document.querySelector('.modal');
document.querySelector('.check').addEventListener('click', () => {
console.log(dialogElem.open);
});
関連リンク
open属性とHTMLDialogElement.showメソッド
dialog要素はopenという属性やJavaScriptのHTMLDialogElement.showメソッドでも開く(表示する)ことができます。
open属性の場合:
<dialog open>
...
</dialog>
HTMLDialogElement.showメソッドの場合:
document.querySelector('.open-modal').addEventListener('click', () => {
document.querySelector('dialog').show();
});
ただし、open属性またはHTMLDialogElement.showメソッドは、あくまでdialog要素を見える状態にするのみで、CSSの::backdrop疑似要素などは表現されませんので、ご注意ください。
最後に
いかがでしょうか、簡単に実装することができたかと思います。今回はほとんど触れていませんが、モーダルウィンドウ自体の見た目についてもCSSで容易に変更することができますので、ぜひお試しください。
