詳細度 からカスケードレイヤー
詳細度とは
ある要素のCSSを決定するためのアルゴリズム。
詳細度の強さ
!important
1-0-0-0-0
インラインスタイル
0-1-0-0-0
ID
0-0-1-0-0
クラス
0-0-0-1-0
要素型
0-0-0-0-1
例
<div id="block" class="block">
<p id="content" class="content">test</p>
</div>
#block {
color: red;
}
.content.content {
color: lightblue;
}
[id="content"].content {
color: blue;
}
div > p.content {
color: coral;
}
この場合は blue になる。
詳細度はここで計算できます。Specificity Calculator
ちなみに styled-component でもスタイルが衝突して優先順位を上げたい際に &&(.class.class) は紹介されてます。
styled-components: Basics
詳細度のまとめ
カスケードレイヤーとは
CSSカスケードレイヤーは、CSSの厄介な問題を解決することを目的としている。
最近だとIEが消えたので全ブラウザーでサポートされるようになった。
カスケードレイヤーが解決したい厄介な問題
固有値の衝突
セレクタが競合するため、サードパーティーなどのスタイルをオーバーライドしたい状況など。
以下のような方法で競合を避けるようにしてきた。
方法論
-
BEM
<section> <div class="article"> <h1 class="article__header"></h1> <img class="article_image" src="..."/> <button class="article__button--disabled" type="button">Link</button> </div> </section>
-
OOCSS
<section> <div class="article"> <h1 class="header header-bold"></h1> <img class="image image-w128" src="..."/> <button class="button button-disabled" type="button">Link</button> </div> </section>
-
SMACSS
<section class="l-content"> <div class="article"> <h1 class="article-header"></h1> <img class="article-image" src="..."/> <button class="button is-disabled" type="button">Link</button> </div> </section>
-
FLOCSS
<section> <div class="c-article"> <h1 class="c-article-header"></h1> <img class="c-article-image u-w128" src="..."/> <button class="c-button u-disabled" type="button">Link</button> </div> </section>
-
ライブラリの使用
- CSS Modules
- Styled Components
- tailwindcss
などカスケードを回避するためにいろいろなベストプラクティスが考えられてきた。
セレクタの順序
実際にはカスケードレイヤーはIDセレクターより強く、style属性より弱い優先度となっている。
一番優先されるスタイルは Origin (ブラウザ)
一番優先されるのは ブラウザの style 。これに対して!important
を使っても一部書き換えることはできなくなっている要素が存在する。iframe:fullscreen
など。また、カスケードレイヤーにも同じスタイルが適応される。他にもShadow Context を使えば Host の style を!imporant
で優先順位を逆転することもできる。
レイヤーの重なり順
@layer layer-1 { a { color: red; } }
@layer layer-2 { a { color: orange; } }
@layer layer-3 { a { color: yellow; } }
a { color: green; }
とあったら、 unlayered style が一番優先されるため、次にlayer-3,layer-2,layer-1と続く。
ここでは a
は green
になる。
@layer layer-1 { a { color: red !important; } }
@layer layer-1 { a { color: blue !important; } }
@layer layer-2 { a { color: orange !important; } }
@layer layer-3 { a { color: yellow !important; } }
a { color: green !important; }
ただ、 important layer が存在する場合、important が出現した順に優先される。
この場合はlayer-1
の red
か blue
。また同名のレイヤーがある場合は後のレイヤーが優先されるため、 a
は blue
になる。
レイヤーの構文
-
レイヤー定義
@layer custom-layer;
-
同じ名前のレイヤーにどこからでもスタイルを追加できる
@layer custom-layer; @layer custom-layer { a { color: red; } }
-
自身でレイヤーの順序リストを定義することもできる
@layer lower-layer, upper-layer;
-
グループ化してスタイルも追加できる
@layer parent { @layer child1, child2; @layer child1 { a: { color: red; } } @layer child2 { a: { color: blue } } } @layer parent.child2, parent.child1; @layer paren.child2 { a: { color: black } }
-
外部からレイヤーを読み込むこともできる
@import url('example.css') layer(custom-layer); @layer custom-layer { ... }
-
レイヤー階層を戻す(ロールバック)
@layer first-layer, second-layer; @layer first-layer { a: { color: black } } @layer second-layer { a: { color: red } a:active { color: revert-layer; } }
<link rel="stylesheet" href="remedy.css" layer="reset">
<style layer="reset">
audio[controls] { display: block; }
</style>
みたいにlayer
を指定してcss
を読み込める時代が来るかもしれない... 🤔
参考
https://developer.mozilla.org/ja/docs/Web/CSS/Specificity
https://css-tricks.com/css-cascade-layers/
https://developer.mozilla.org/en-US/docs/Web/CSS/@layer
https://github.com/w3c/csswg-drafts/issues/5853
Discussion