TL;DR

同じ要素に対して競合する CSS の宣言があるとき、どれを適用するかを決めるためのセレクタの重み。英語では Specificity という。

仕組み

ブラウザはまずオリジンと重要度(!important)でカスケードを決め、同じ条件の中で競合した宣言を詳細度で比べる。

詳細度は ID、CLASS、TYPE の 3 つの列で数える。

列数えるもの例重み
IDID セレクタ#main1-0-0
CLASSクラス、属性セレクタ、擬似クラス.btn、[type="text"]、:hover0-1-0
TYPE要素型セレクタ、擬似要素p、::before0-0-1

左の列から順に比べ、最初に差が出た列で優先順位が決まる。TYPE の列がいくつあっても、CLASS の列 1 つには勝てない。詳細度がすべて同じなら、後に書いた宣言が優先される。全称セレクタ * と結合子(>、+、~、空白)は詳細度に影響しない。

例

#myElement {
  color: green;
} /* 1-0-0。こちらが適用される */
.a .b .c .d [id="x"] {
  color: yellow;
} /* 0-5-0 */

:is()、:not()、:has() は、それ自体は重みを持たず、引数の中で最も詳細度の高いセレクタの重みが加わる。:where() は引数にかかわらず常に 0-0-0 になる。

注意点

インラインスタイル(style="...")は、どのセレクタよりも優先される。!important は詳細度とは別の仕組みで、同じオリジンとレイヤーの中では通常の宣言より優先される。MDN は !important を悪い習慣としており、使うなら理由をコメントに残すよう勧めている。詳細度に頼らずに優先順位を制御するには、カスケードレイヤー(@layer)を使う。

出典