ネイティブ <dialog> モーダル
<dialog> 要素 + showModal() メソッドで実装するネイティブモーダル。トップレイヤー描画・focus trap・Escape キー閉じ・backdrop 装飾まで標準実装。
解説
ネイティブ <dialog> モーダルは、UI コンポーネントカテゴリの「モーダル」に分類される実装パターンです。CSS と JavaScript の組み合わせで構成され、難易度はシンプルレベル。
HTML5 の <dialog> タグは、モーダル UI に必要な機能(フォーカストラップ、Escape キー閉じ、トップレイヤー描画、backdrop)をブラウザ標準で実装してくれます。これまで「react-modal」「a11y-dialog」のようなライブラリで複雑に実装していた処理が、dialog.showModal() 一行で動きます。
このサンプルでは、「利用規約を表示」ボタンクリックでモーダルが開き、method="dialog" な form の送信ボタンで自動的に閉じる実装をしています。アクセシビリティ的にも完璧で、スクリーンリーダー対応・キーボード操作対応がすべて自動で行われます。
仕組み
下記コードタブから HTML / CSS / JS をそれぞれ確認・コピーできます。プレビュー領域では実際の動作をその場で確認可能です。
WAI-ARIA 属性を活用したアクセシブルな実装です。スクリーンリーダー・キーボード操作にも配慮しています。
注意点 / カスタマイズ時のポイント
全主要ブラウザで対応済み(Chrome 37+、Safari 15.4+、Firefox 98+、Edge 79+)。showModal() ではなく show() を呼ぶと、モーダル化されず inline dialog として開くので注意。
背景クリックで閉じる動作は標準ではないので、JS で close() を呼ぶ実装を別途必要。
使用例・適したシーン
- 利用規約・プライバシーポリシー表示
- 画像拡大表示
- 確認ダイアログ
よくある質問
アニメーション付きで開閉したい
dialog[open] + ::backdrop に transition や animation を当てればできます。display: none ↔ display: grid の transition には @starting-style や transition-behavior: allow-discrete を併用すると滑らかになります。背景クリックで閉じたい
dialog.addEventListener('click', e => { if (e.target === dialog) dialog.close() }) を書きます。クリックターゲットが dialog 要素自体(=モーダル外側)なら閉じる、というロジックです。このスニペットは商用利用できますか?
そのまま貼り付ければ動きますか?
ブラウザ対応は?
jQuery でも書けますか?
document.querySelector を $() に置き換える程度で動作しますが、近年は jQuery を使わない方が軽量で推奨されます。