💡 この記事でわかること
- dialog要素とは何か
- 基本的な書き方(showModal・close)
- 背景(バックドロップ)クリックで閉じる方法
- ::backdropでの見た目のカスタマイズ
- 初心者がつまずきやすいポイント
1. dialog要素とは?
dialog要素とは、
👉 画面の上に重ねて表示する「モーダルウィンドウ(ポップアップ)」を作るためのタグです。
確認メッセージやログインフォーム、利用規約の表示など、ページ本体の操作を一旦止めて注目させたい内容を表示する場面でよく使われます。
👉 details・summary要素についての記事はこちら
💡 これまでモーダルウィンドウはCSSとJavaScriptを組み合わせて自作するのが一般的でしたが、dialog要素を使うと開閉の仕組みやフォーカス管理の一部をブラウザ標準の機能に任せられます。
2. 基本的な書き方
dialogタグの中に表示したい内容を書き、JavaScriptからshowModal()メソッドを呼び出すことでモーダルとして開きます。
<dialog id="myDialog">
<p>これはモーダルウィンドウです。</p>
<button id="closeBtn">閉じる</button>
</dialog>
<button id="openBtn">開く</button>
const dialog = document.getElementById("myDialog");
const openBtn = document.getElementById("openBtn");
const closeBtn = document.getElementById("closeBtn");
openBtn.addEventListener("click", () => {
dialog.showModal();
});
closeBtn.addEventListener("click", () => {
dialog.close();
});
👉 showModal()で開くと、ページの他の部分は暗く重なる背景(バックドロップ)で覆われ、Tabキーでのフォーカス移動もdialogの中に閉じ込められます。何もCSSを書かなくても、中央寄せの表示・背景の半透明オーバーレイまで自動で用意されます。
3. 背景クリックで閉じる
dialog要素には、背景(バックドロップ)をクリックしても自動では閉じない仕様になっています。背景クリックで閉じたい場合は、クリックされた場所がdialog自身かどうかを判定するコードを書きます。
dialog.addEventListener("click", (event) => {
if (event.target === dialog) {
dialog.close();
}
});
💡 dialog要素自体が画面いっぱいに広がっていて、その中身(padding部分)をクリックしたときはevent.targetがdialog自身になる、という性質を利用した判定方法です。
4. ::backdropで見た目をカスタマイズする
モーダル表示中にページ全体を覆う背景の部分は、::backdrop擬似要素でスタイルを指定できます。
dialog::backdrop {
background: rgba(0, 0, 0, 0.6);
}
dialog {
border: none;
border-radius: 8px;
padding: 24px;
}
5. 初心者がつまずきやすいポイント
show()とshowModal()の違い
dialog要素にはshowModal()以外にshow()というメソッドもあります。show()で開いた場合はモーダルにならず、背景オーバーレイもフォーカスの閉じ込めも起きず、ページの他の部分をそのまま操作できる状態で表示されます。「注目させたい」ならshowModal()、「軽い通知のように表示したい」ならshow()、という使い分けを意識しましょう。
CSSのdisplayだけでは開閉できない
dialogタグはopen属性を付けるだけでも見た目上は表示されますが、その場合はshowModal()で開いたときのようなモーダル表示(背景オーバーレイやフォーカス管理)にはなりません。モーダルとして使いたい場合は、必ずJavaScriptからshowModal()を呼び出す必要があります。
まとめ
dialog要素を使うと、標準機能だけでモーダルウィンドウを作れます。
- showModal()で開く・close()で閉じる
- 背景クリックでの自動クローズは自分でイベントを書く必要がある
- ::backdrop擬似要素で背景の見た目を調整できる
- show()とshowModal()では背景オーバーレイの有無が異なる
まずは簡単なdialogタグを1つ用意して、showModal()で開いてみましょう。