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
単位でまとめておくことで記述を追加したりリファクタリングの際に予期せぬ上書きを防ぐことができそうです