📋
定義されたCSS変数が::backdrop内で参照できない
モダンブラウザで <dialog> 要素が対応し始めて、モーダルウィンドウを <dialog> 要素を使って実装してみたときに気づいた現象です。
CSS 変数が参照できない?
::backdrop 擬似要素を使って <dialog> が開いたときの背景色を指定してみます。
:root {
// モーダルウィンドウの背景色を定義
--bg: rgb(0 0 0 / 15%);
}
dialog::backdrop {
// モーダルウィンドウが開いたときの背景色に指定
// 反映されない!?
background-color: var(--bg);
}
すると、変数 --bg が参照されずに背景色が適用されません。
仕様を見てみる
WHATWG の仕様 を見てみると、次のように書かれています。
It does not inherit from any element and is not inherited from.
どの要素からも継承されず、また継承されることもない。
つまり、::backdrop 内で CSS 変数を参照できないのは仕様ということみたいです。
解決策
継承されないので、:root と ::backdrop の両方で定義しておく必要があります。
:root {
// グローバル変数用
--bg: rgb(0 0 0 / 15%);
}
::backdrop {
// <dialog>変数用
--bg: rgb(0 0 0 / 15%);
}
dialog::backdrop {
background-color: var(--bg);
}
ちなみに、次のようにセレクタをまとめて書くとブラウザが ::backdrop 擬似要素に対応していないときに :root で定義された CSS 変数自体も無効となってしまうので分けて書きます。
:root, ::backdrop {
// まとめて書くのはNG
--bg: rgb(0 0 0 / 15%);
}
dialog::backdrop {
background-color: var(--bg);
}
それを防ぐための救世主 :is() セレクタがありますが、これを使うとなぜか ::backdrop 内で CSS 変数が無効となってしまいます。これはバグなのか仕様なのかはわかりません。
:is(:root, ::backdrop) {
--bg: rgb(0 0 0 / 15%);
}
dialog::backdrop {
// 効かない
background-color: var(--bg);
}
なので、今のところは素直に分けて書く以外の方法はなさそうです。
Discussion