CSS 詳細度計算機
リファレンス任意の CSS セレクターの詳細度 (A, B, C) を計算します — ID、クラス、属性、擬似クラス、要素を処理し、複数セレクターを同時に比較し、各部分の貢献を分解表示します。:is()、:not()、:where() に対応。
このページの内容
CSS の詳細度とは?#
2 つの CSS ルールが同じ要素の同じプロパティを設定しようとしたとき、ブラウザは後ろに書かれた方ではなく、詳細度 が高い方を選びます。詳細度は 3 部構成のスコア (A, B, C) で、カスケードはこれをバージョン番号のように比較します。
- A — ID セレクター(
#header)。 - B — クラスセレクター(
.btn)、属性セレクター([type=email])、擬似クラス(:hover、:focus)。 - C — 要素セレクター(
div、a)と擬似要素(::before、::first-line)。
最初に A を比較し、同じなら B、次に C へ。ID が 1 つ (1,0,0) は、いくつクラスがあっても (0,99,99) に勝ち、それはさらにいくつ要素があっても勝ちます。ユニバーサル *、結合子(> + ~)、ネストセレクター & は何も加えません。
本ページは、貼り付けた任意のセレクターのこのタプルを計算します — モダンな関数擬似クラス :is()、:where()、:not()、:has() や、:nth-child() の of S 節も含めて — セレクターのリストを順位付けし、どの部分が何に貢献したかを正確に示します。普遍的な CSS の疑問「なぜ私のルールが負けているのか?」に答える最速の手段です。
使い方#
- サンプル をクリックして作例のセレクターセットを読み込むか、ボックスを消して独自のものを貼り付けます。単独のセレクター(
#nav .item)でもルール全体(#nav .item { color: red })でも構いません — ツールは{の前の部分を読み取ります。 - 複数のセレクターがありますか? カンマで区切ると、最も詳細なものから順にランク付けされ、勝者がフラグ付けされます。
- 右ペインに各セレクターとその
(A, B, C)タプル、貢献した各部分の色付き内訳(赤 = ID、青 = クラス/属性/擬似クラス、緑 = 要素/擬似要素)がリストされ、スコアが なぜ その値なのかが分かります。 - 右上の色付き凡例が、どのドットが A/B/C に対応するかを思い起こさせます。
- ルールに
!importantが含まれていた場合、情報の注記が現れます —!importantは詳細度比較の 中ではなく、その上 に位置する宣言レベルの上書きです。
主な機能#
- 難しいケースに正確。
:where()は常に(0,0,0)を貢献し、:is()/:not()/:has()は引数の中で 最も高い 詳細度を採り、レガシーな:beforeと:nth-child()のof S節は Selectors Level 4 に従って処理されます。 - カンマ区切りリストをランク付け し、同点をフラグ付けするため、複数のルールのどれが勝つか一目で分かります。
- 部分ごとの内訳。 すべての
#id、.class、[attr]、:pseudo-class、::pseudo-element、要素が、それが貢献した正確なテキストとともに項目化されます。 - ルール全体に寛容。
a:hover { text-decoration: underline }を貼り付けると — コメントは剥がされ、宣言ブロックは自動的に無視されます。 - 100% ローカル。 ページの外には何も出ず、スタイルシートは取得も評価もされません。
実例#
よくあるデバッグの難問です。3 つのルールが同じリンクを対象とし、誤った色が勝ってしまいます。これらをボックスに貼り付けます。
.button:hover
:is(.card, #hero) .button
a.button
出力はこれらをランク付けします。
| 順位 | セレクター | タプル |
|---|---|---|
| 1 | :is(.card, #hero) .button | (1, 1, 0) — 勝者 |
| 2 | .button:hover | (0, 2, 0) |
| 3 | a.button | (0, 1, 1) |
勝者はクラスを最も多く持つものではありません。:is(.card, #hero) は引数の中で 最も高い 詳細度を継承します — #hero は ID なので、.card なら (0,1,0) でも :is() は (1,0,0) を持ちます。.button を足して B を 1 つ増やし、(1,1,0) になります。A 列のこの ID 1 つが、.button:hover の 2 クラス (0,2,0) に勝ちます — これこそ、:is() をプロダクション CSS で危険にする正確な落とし穴です。
同じグループ化を、詳細度を上げずに作りたいなら、:is() を :where() に替えます。
:where(.card, #hero) .button → (0, 1, 0)
これで a.button から要素を引いたものと同点になり、ソース順が決定します。これが :where() が存在する全理由です。
よくある質問#
なぜ ID 1 つが何百ものクラスに勝つのですか?#
詳細度は合計ではなく、バージョン番号のように左から右へ列を比較します。(1,0,0) は (0,999,999) より「上位」です — 最初の列 A が前者では非ゼロ、後者ではゼロだからで、B 列と C 列は参照すらされません。これは意図的なもので — ID は曖味さのない単一であることを意図していました。
:is() と :where() の違いは何ですか?#
マッチするものは同じですが、詳細度は正反対です。:is(.a, #b) は引数の中で 最も高い 詳細度を採るため(#b が (1,0,0) にします)、:where(.a, #b) は引数に関わらず常に (0,0,0) を貢献します。簡単に上書きできる低詳細度の既定値には :where() を、結合したセレクターに本当に競争させたい場合は :is() を使います。
インラインの style="…" 属性はこれらに勝ちますか?#
はい。インラインスタイルは通常のカスケードではセレクターベースのあらゆるルールより優先されます(より高いカスケードオリジンに位置するため)、!important なしではどのセレクタータプルもインラインスタイルを上書きできません。これは (A,B,C) スコアとは別の軸であり、ツールがセレクターだけを評価する理由です。
!important はどこに位置しますか?#
!important はセレクターのプロパティではなく、宣言レベルのフラグです — (A,B,C) タプルは変えません。宣言全体をより高いカスケードオリジンへ移動させるため、!important ルールは詳細度に関わらず通常ルールに勝ちます。ツールはその存在を情報として注記しますが、スコアには入れません。