👌
CSSカスケード ~詳細度~
前回の続き
詳細度とは
詳細度とは、どのスタイルが優先されるかを決める仕組みのこと。
CSSのスタイル適用の優先順位は「オリジンと重要度」「カスケードレイヤー」「詳細度」「スコープ近接性」「記述順」となるが、詳細度はこの中で3番目の優先順位となる。
つまり、「オリジンと重要度」「カスケードレイヤー」が共に同じ場合、詳細度によってどのスタイルが優先されるかが決まる。
MDNのドキュメント
詳細度の表し方
詳細度は「A-B-C」という3つの数値で表される。A, B, Cの意味は以下の通り。
- A: IDセレクター(
#id
)の数 - B: クラス(
.class
)、属性([attr]
)、疑似クラス(:hover
など)の数 - C: 要素型(
div
など)と疑似要素(::before
など)の数
例
[type="password"], /* 0-1-0 */
input:focus, /* 0-1-1 */
:root #myApp input:required /* 1-2-1 */
{
color: blue;
}
詳細度の比較
以下のcssがあるとする。
#myElement {
color: green; /* 1-0-0 */
}
.bodyClass .sectionClass .parentClass [id="myElement"] {
color: yellow; /* 0-4-0 */
}
そして以下のhtmlがあるとする
<div class="bodyClass">
<div class="sectionClass">
<div class="parentClass">
<input id="myElement">
</div>
</div>
</div>
このとき <input id="myElement">
はどのスタイルが適用されるか。
この場合、詳細度が高いのは#myElement
のため文字色はgreenになる。
詳細度は左の数字から比較する。
細かな仕様
:is()
:not()
:has()
これら3つは詳細度の計算においては擬似クラスとはみなされない。
代わりに引数のセレクターが詳細度の計算に使われる。
:is()の場合、引数のなかではもっとも詳細なものを採用する。
div:is(.test) p {
/* 0-1-2 */
/* IDは0 クラスが1つ(.test) 要素が2つ(div, p) */
/* :is()は擬似クラスだが詳細度に含まれない */
}
div:is(.test, #fakeId) p {
/* 1-0-2 */
/* IDが1つ(#fakeId) クラスが0 要素が2つ(div, p) */
/* :is()の引数は#fakeIdが採用される */
}
CSS入れ子に対してもis()
と同じ計算になる。
p,
#fakeId {
span {
/* 1-0-1 */
/* 「:is(p, #fakeId) span」と書いたときと同じ */
}
}
where()
引数の中のセレクターは詳細度に影響を与えない
:where(#defaultTheme) a {
/* 0-0-1 */
/* 要素が1つ(a)
}
@scope
詳細度に影響を与えない。
:scope
は擬似クラスとして詳細度に関わるので混同しないように注意。
@scope (.light-theme) {
:scope {
/* 0-1-0 */
/* 擬似クラスが1つ(:scope) */
}
p {
/* 0-0-1 */
/* 要素が1つ(p) */
}
}
Discussion