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で容易に変更することができますので、ぜひお試しください。