📋
定義された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