内容
CSSの詳細度と、コーディングで注意したい事をまとめてみました。
詳細度(specificity)とは
記述したCSSのプロパティが適用される際の優先度です。
詳細度が高いもののプロパティが適用されます。
詳細度が同じ場合は、後から記述されたものが適用されます。
この詳細度は、CSSのセレクターによって決定されます。
#詳細度の計算の仕方
詳細度は、セレクタの内容から算出します。
下記のように値が設定されており、これを並べた値が詳細度になります。
- セレクター内のID属性の数(a)
- セレクター内のCLASS属性/属性セレクタ/疑似クラスの数(b)
- セレクター内のタグ名/擬似要素の数(c)
/* 例 */
* /* a=0 b=0 c=0 -> specificity = 0 */
LI /* a=0 b=0 c=1 -> specificity = 1 */
UL LI /* a=0 b=0 c=2 -> specificity = 2 (要素セレクタが2つ) */
UL OL+LI /* a=0 b=0 c=3 -> specificity = 3 (要素セレクタが3つ) */
H1 + *[REL=up] /* a=0 b=1 c=1 -> specificity = 11 */
UL OL LI.red /* a=0 b=1 c=3 -> specificity = 13 (要素セレクタが3つとclassセレクタ)*/
LI.red.level /* a=0 b=2 c=1 -> specificity = 21 */
#x34y /* a=1 b=0 c=0 -> specificity = 100 */
#s12:not(FOO) /* a=1 b=0 c=1 -> specificity = 101 */
引用元:https://drafts.csswg.org/selectors-3/#specificity
コーディングで注意したい事
複雑なセレクタにしてしまうと、意図しないプロパティが適用されたり、適用されなかったりする事が増えます。
詳細度を計算するにしても、計算が複雑です。
この為、セレクタを考えるときは下記を念頭に置きたいです。
##同じ形式のセレクタにする(可能な限り)
これは詳細度の統一が目的です。
詳細度を統一しておくと、詳細度を細かく考えなくて済むので簡単になります。
算出する場合も最小限で済みます。
p{
color: black;
}
p.red{
color: red;
}
.info p.text{
color: blue;
}
div p span {
color: green;
}
/* こっちのほうが、どのプロパティが適用されるか簡単に予想できる */
.text{
color: black;
}
.red{
color: red;
}
.info{
color: blue;
}
.green{
color: green;
}
セレクタは単純にする
これも詳細度の統一が目的です。また詳細度の算出を容易にする為の意味もあります。
(また、何の為のstyleであるのか解読に時間がかかります)
/* 元コード */
div p span.note{
color: red;
}
/*
ABテストや、何かの理由で上書きしたい時は、同じように書かないと適応されない。
めんどい
*/
div p span.note{
color: blue;
}
まとめ
- 詳細度によってプロパティの適用が決定される
- 詳細度はセレクタの内容から算出される
- セレクタを単純にすると、詳細度の計算が少なくて済む。
さらに突き詰めると、BEMやsmacss、flocssのような設計手法/思想に行き着きます。
まずは詳細度でプロパティの適用が変わる事、詳細度を統一する事を意識する事で、だいぶCSSのコーディングと運用が楽になると思います。
参考
詳細度
https://developer.mozilla.org/ja/docs/Web/CSS/Specificity
Selectors Level 3
https://drafts.csswg.org/selectors-3/#specificity