🎯 CSS詳細度の計算

CSSセレクタを入力すると、詳細度を (a, b, c) で算出します。ID・クラス・要素などの内訳を1つずつ表示し、複数のセレクタを入れれば優先順位の高い順に並べ替えて「どちらが勝つか」を比較できます。:is() / :not() / :where() や全称セレクタ、結合子の扱いも正しく数えます。

入力

複数行を入れると、詳細度の高い順に並べて比較します。空行は無視します。

各セレクタの詳細度 (a, b, c)

セレクタを入力すると、ここに (a,b,c) と内訳が表示されます。

a = IDセレクタ、b = クラス・属性・擬似クラス、c = 要素型・擬似要素の数です。比較は a → b → c の順で、下位の桁が上位を追い越すことはありません(桁上がりしない)。

解説

詳細度(Specificity)は、同じ要素に複数のCSSルールが当たったとき「どの宣言が勝つか」を決める仕組みです。ブラウザはセレクタごとに重みを計算し、値が大きいルールを優先します。この重みは1つの数字ではなく (a, b, c) という3つの成分の組で表され、上位の成分から順に比較されます。a が多い方が無条件で勝ち、a が同じなら b、b も同じなら c で決まります。10個の c が1個の b に勝つことはありません(桁上がりしない)。本ツールは、入力したセレクタを解析してこの (a, b, c) を求め、内訳を1つずつ示します。

数え方は次のとおりです。a は ID セレクタ(#id)の個数。b はクラス(.class)・属性セレクタ([type="text"])・擬似クラス(:hover、:nth-child() など)の個数。c は要素型セレクタ(div、a など)と擬似要素(::before、::placeholder など)の個数です。たとえば「#nav .item a:hover」なら、ID が1つ(a=1)、.item と :hover で b=2、要素 a で c=1、合わせて (1, 2, 1) になります。「ul li」は要素が2つなので (0, 0, 2) です。

カウントしない・特別扱いする要素もあります。全称セレクタ * は詳細度に加算しません(0)。子・隣接・間接兄弟・子孫の各結合子(>、+、~、空白)も数えません。関数擬似クラスのうち :where() は常に 0 として扱われ、中身が何であっても詳細度を上げません。一方 :is()・:not()・:has() は、引数として渡したセレクタリストの中で最も詳細度が高いものの値をそのまま採用します。たとえば :is(.a, #b) は #b の (1,0,0) を採り、:not(.foo) は (0,1,0) を加えます。本ツールはこれらを再帰的に解析して反映します。

セレクタの詳細度より強い仕組みが2つあります。1つはインラインスタイル(style="…")で、これはセレクタで書くどのルールより優先されます。もう1つは !important で、これが付いた宣言は詳細度の比較をすり抜けて最優先になります(!important 同士なら、その中で改めて詳細度とソース順で決まります)。また詳細度が完全に同点のときは、後から読み込まれた(=CSS上で後に書かれた)ルールが勝ちます。設計上は詳細度を無闇に上げず、同点をソース順で解決できる素直なセレクタ設計が保守しやすくなります。すべての計算は端末内で行い、入力内容はどこにも送信されません。

よくある質問

(a, b, c) はどういう意味ですか?

詳細度を表す3つの成分です。a は ID セレクタの数、b はクラス・属性・擬似クラスの数、c は要素型・擬似要素の数を表します。比較は a → b → c の順で行い、上位の成分が大きい方が優先されます。古い資料では「100・10・1 の重み」と説明されることもありますが、実際には桁上がりしないため、3つの数字の組として比較するのが正確です。

クラスをたくさん重ねれば ID に勝てますか?

勝てません。詳細度は桁上がりしないため、クラスや擬似クラス(b 成分)をいくつ並べても、ID が1つでも多い(a 成分が大きい)セレクタには勝てません。たとえば #id (1,0,0) は .a.b.c.d.e.f.g.h.i.j.k (0,11,0) にも勝ちます。

:is() / :not() / :where() はどう数えますか?

:where() は中身に関わらず常に 0 で、詳細度を上げません。:is()・:not()・:has() は、引数として渡したセレクタリストの中で最も詳細度が高いものの値を採用します。たとえば :is(.a, #b) は #b の分だけ a=1 が加わります。本ツールはカッコの中を再帰的に解析して反映します。

全称セレクタ * や結合子(> + ~)は数えますか?

どちらも詳細度には加算しません。* は 0、子結合子 >・隣接兄弟 +・間接兄弟 ~・子孫(空白)はセレクタ同士をつなぐ記号なので数えません。したがって「* > .box」の詳細度は .box と同じ (0,1,0) です。

!important やインラインスタイルはどう扱われますか?

!important は詳細度の比較そのものをすり抜けて最優先になります(本ツールはセレクタの詳細度を計算するもので、!important の有無は反映しません)。インラインスタイル style="…" はセレクタで書くどのルールより優先され、概念的には a よりさらに上の桁に位置づけられます。設計上は、これらに頼りすぎるとオーバーライドが難しくなるため注意してください。

詳細度が同点のときはどちらが勝ちますか?

(a, b, c) が完全に等しいときは、後から適用されるルール、つまり CSS 上で後に書かれた(あるいは後に読み込まれた)宣言が勝ちます。これを「ソース順(source order)で後勝ち」と言います。本ツールの優先順位一覧でも、同点のセレクタは「=」で示し、入力順で下にあるものが実際には勝つ旨を注記します。

属性セレクタや擬似クラスは b ですか c ですか?

属性セレクタ([type="text"] など)と擬似クラス(:hover、:first-child、:nth-child() など)は b に数えます。クラスと同じ重みです。一方、擬似要素(::before、::after、::placeholder など)は c で、要素型と同じ重みです。:before のような旧記法の擬似要素も c として扱います。

入力したセレクタはサーバーに送られますか?

送られません。解析と計算はすべてブラウザ内で完結し、入力内容はどこにも送信されません。直前の入力は次回のために端末内(localStorage)にのみ保存されます。オフラインでも利用できます。