“CSS の C (Cascading) を見つめ直す” のおかげで CSS のカスケードがちょっと1分かったので、早速、
Widely available になってから 1年以上経っている。 また、いくつかの UIコン ポーネント・CSS ラ イブラリでも使われるようになっている
、カスケードレイヤー をいじってみる。
いじる
カスタムプロパティ (--color) 上書きしながら @layer のふるまいを検証する。
最初
body {
background-color: var(--color);
}
--color が未定義だから、白背景 (playground)。
red レイヤーを追加
/** 👇️ */
@layer red {
:root {
--color: red;
}
}
body {
background-color: var(--color);
}
--color が定義された結果、赤背景になる (playground)
red レイヤーの後に blue レイヤー を追加
@layer red {
:root {
--color: red;
}
}
/** 👇️ */
@layer blue {
:root {
--color: blue;
}
}
body {
background-color: var(--color);
}
Cascade layers (like declarations) are ordered by order of appearance. (…) then for normal rules the declaration whose cascade layer is last wins, (…)
レイヤーは出現順に並べられ、最後にある宣言が優先される。 そのため、青背景になる (playground)。
blue レイヤーの後に green レイヤー を追加
@layer red {
:root {
--color: red;
}
}
@layer blue {
:root {
--color: blue;
}
}
/** 👇️ */
@layer green {
:root {
--color: green;
}
}
body {
background-color: var(--color);
}
最後に宣言された緑背景になる (playground)。
ファイルの先頭でレイヤーを宣言する
/** 👇️ */
@layer green, blue, red;
@layer red {
:root {
--color: red;
}
}
@layer blue {
:root {
--color: blue;
}
}
@layer green {
:root {
--color: green;
}
}
body {
background-color: var(--color);
}
@layer green, blue, red; でレイヤーの順番が決まっているので、その後に宣言した @layer green {} は記述の green レイヤーに割り当てられる。
Explicit layer identifiers provide a way to assign multiple style blocks to a single layer.
そのため red レイヤーが最も優先度が高く、赤背景になる (playground)。
レイヤーの宣言をずらす
@layer red {
:root {
--color: red;
}
}
/** 👇️ */
@layer green, blue, red;
@layer blue {
:root {
--color: blue;
}
}
@layer green {
:root {
--color: green;
}
}
body {
background-color: var(--color);
}
@layer red{} の次に @layer green, blue, red; が宣言されているため、レイヤーの順番は red -> green -> blueになる。
そのため、青背景になる(playground)。
匿名レイヤーを追加する
@layer green, blue, red;
/** 👇️ */
@layer {
:root {
--color: yellow;
}
}
@layer red {
:root {
--color: red;
}
}
@layer blue {
:root {
--color: blue;
}
}
@layer green {
:root {
--color: green;
}
}
/** 👇️ */
@layer {
:root {
--color: purple;
}
}
body {
background-color: var(--color);
}
になる。匿名レイヤーは、宣言ごとに一意のものとして扱われる。
anonymous segments have unique identities for each occurrence.
そのため上記のレイヤー順は:
greenbluered<anonymouse><anonymouse>
になり、紫背景になる (playground)。
@layer を使わずに宣言する (implicit final layer)
/** 👇️ */
:root {
--color: orange;
}
@layer green, blue, red;
@layer {
:root {
--color: yellow;
}
}
@layer red {
:root {
--color: red;
}
}
@layer blue {
:root {
--color: blue;
}
}
@layer green {
:root {
--color: green;
}
}
@layer {
:root {
--color: purple;
}
}
body {
background-color: var(--color);
}
@layer を使わない宣言は implicit final layer に追加される。
For the purpose of this step, any declaration not assigned to an explicit layer is added to an implicit final layer.
final なので、レイヤー順において一番優先されるレイヤーになるため、オレンジ背景になる(playground)。
(余談) カスケードレイヤーが解決すること
ref: MDN - カスケードレイヤー - カスケードレイヤーが解決できる課題
大規模なコードベースでは、(…)
大規模なコードベースのスタイルは様々なところから提供される:
- 複数のチーム
- コンポーネントライブラリー
- フレームワーク
- サードパーティ
それらは作成者スタイルシート内でカスケードされる。辛すぎ。
多くのソースから提供されたスタイルが一緒にカスケードされること、(…)
チーム・人によってカスケード値を決める方法が違うかもしれない。辛すぎ。
詳細度の競合は、すばやくエスカレートする可能性があります。(…)
!important での解決はありがちだけれど、競合を通常の宣言から重要な宣言に移しているだけ。辛すぎ。
カスケードオリジンがユーザー、ユーザーエージェント、作成者スタイル間のパワーバランスを提供するのと同じように、カスケードレイヤーは、(…)
カスケードレイヤーはサブオリジンがあるかのように、構造的に整理する方法。
レイヤー内のルールは、レイヤー外のスタイルルールと競合することなく、互いにカスケードされます。(…)
カスケードレイヤーを使えば、レイヤーごとにスタイルを独立させられるので、細かい競合を気にせずに済む。嬉しすぎ。
レイヤーの優先順位は、常にセレクターの詳細度よりも優先されます。(…)
レイヤー間の詳細度の懸念はない。嬉しすぎ。
Footnotes
-
ほんとうの意味で、ちょっと。 ↩