モーダルはネイティブの dialog で:無料で付いてくるものが多い

自前のモーダルはフォーカストラップ、ESC、スクロール固定、フォーカス復帰を全部書くことになる。dialog と showModal なら全部入りで ::backdrop も使える。

モーダルを作るときの既定は変わりました。<div class="overlay"> ではなく、ネイティブの <dialog> と showModal() です。

showModal が無料でくれる 4 つ

showModal() は open 属性とは別物で、要素をトップレイヤーに載せます。その結果、普段は自分で書く 4 つが組み込みの挙動になります。

  • フォーカストラップ:Tab が背後のページへ抜けず、支援技術から見て背景は inert
  • ESC で閉じる:keydown を自分で監視せず、閉じたときのイベントは close
  • スクロール固定:背後の文書が止まり、body に overflow: hidden を足す必要もない
  • フォーカス復帰:閉じるとブラウザが開いた要素へフォーカスを戻す

トップレイヤーは z-index の問題も同時に片づけます。モーダルは常に最前面で、overflow: hidden の祖先に切り取られず、ヘッダーに大きな z-index を足す必要もありません。

唯一の罠は ::backdrop

覆いは dialog の背景ではなく、同じ名前の擬似要素です。

dialog::backdrop {
  background: color-mix(in srgb, var(--c-ink) 60%, transparent);
}

::backdrop はトップレイヤーの独立したボックスなので、dialog に書いたカスタムプロパティを継承しません。サイトのトークンを読ませたいなら dialog ではなく :root に定義します。ここが一番混乱しやすいところです。

自前の層が正しい場合

このサイトのツール画面には純 CSS の ui-overlay(結果パネル、読み込み中の表示)があります。あれは表示層であってモーダルではありません。閉じ込めるフォーカスも、操作もなく、スクロールして流れ去って構わないものです。本当のモーダル(削除の確認など)は dialog を使います。

ネイティブ要素で足りるなら自前で作らない。自作の理由は見た目だけにしておく。

← 記事一覧に戻る

コメント

…