CSS の Cascade Layers を触ってみた
Chromium Blog: Chrome 99: CSS Cascade Layers, a New Picker for Input Elements, and More
CSS の Cascade Layers が Google Chrome 99 で実装されるという事なので勉強してみます
まずは仕様確認
6.4. Cascade Layers - CSS Cascading and Inheritance Level 5
層というとペイント系ツールの表示の層とか CSS なら z-index とかのコンテンツ表示の層を連想しますが 6.2. Cascading Origins - CSS Cascading and Inheritance Level 5 に新たな層の加える話らしいです
試しに書いてみるとこんな感じ
<title>CSS @Layer test</title> <style> @layer base, value, override; p { color:black; background-color: white; } @layer value { :root { --green: green; --blue: blue; } } @layer override { p {color: var(--green);} p.a {color: var(--green);} .b {color: var(--green);} .c {color: var(--green);} .d {color: var(--green);} } @layer base { p {color: var(--blue);} p.a {color: var(--blue);} .b {color: var(--blue);} p > span.c {color: var(--blue);} .d {color: var(--blue) !important;} } </style> <p>Black text.</p> <p class="a">Black text.</p> <p><span class="b">Green text.</span></p> <p><span class="c">Green text.</span></p> <p><span class="d">Blue text.</span></p>
まず @layer の外の記述が @layer 内の記述より優先されます
CSS Selectorによる優先順位より @layer の概念の方が上なので、@layer の外の p への指定が @layer の内の p.a より優先されます
CSSでは先に記述された内容を後に記述した内容が上書きする仕組みになっていますが @layer を使うと名前単位でグループ化でき、 @layer の名前だけを先に記述することでもこの上書き順序を制御できます
@layer base; @layer value; @layer override;
この場合 @layer base を @layer value、それを更に @layer override; が上書きする事になります
これを @layer base, value, override; とカンマ区切りで 1 にまとめることもできます
上記の例では @layer base の p > span.c {color: green;} より @layer override の .c {color: green;} の方が強くなっています
更に @layer より !important 方が優先されるので @layer としては下位でも @layer base の中の !important 付きの記述の方が他の @layer の中の !important がない記述より優先されます
あくまで上書きの優先順位なので、ある @layer から別 @layer のカスタムプロパティーを参照することは @layer による上位、下位に関係なくできます (同じカスタムプロパティーがあれば上書きは発生しますが)
更に @import で外部CSSを読み込む際に layer(...) として @import 先に丸ごと @layer の名前を設定することができます
この時 @import 先の CSS の中で @layer が使われていれば @layer は階層構造作るので @import 元/先で @layer の名前が重複しても意図しない上書きを避ける事ができます
@layer base;
@import url(default.css) layer(default);
@layer override {
/* ... */
}
@import url(theme.css) layer(theme);
@layer base {
/* ... */
}
@layer default {
@layer base {/* ... */}
@layer override {/* ... */}
}
@layer theme.override {
/* ... */
}
とりあえずさっと調べた所ではこんな感じで CSS を @layer 単位でまとめておくことで記述を追加したりリファクタリングの際に予期せぬ上書きを防ぐことができそうです