てもとツール
ツール紹介

CSSの詳細度を確かめる手順|勝つ宣言と決め手まで見る

CSS のセレクタを 1 行に 1 つ書くと、詳細度と部品ごとの内訳、勝つ順が分かります。CSS をまとめて貼れば、同じプロパティのどの宣言が使われるかと、!important・style 属性・レイヤー・詳細度・書いた順のどこで決まったかまで出ます。画面を追って説明します。

公開読了目安 約5分

CSSの詳細度を確かめる手順|勝つ宣言と決め手まで見るのアイキャッチ画像

この記事の要点

  • セレクタを 1 行に 1 つ書くと、強さ(詳細度)と勝つ順が並ぶ
  • どの部品が強さにどれだけ効いたかを、1 つずつ確かめられる
  • CSS をまとめて貼ると、同じ指定のうちどれが使われるかが分かる
  • 負けた指定には、!important・レイヤー・書いた順など、負けた理由が付く
  • HTML は見ないので、貼ったルールがすべて同じ部分に当たるとして比べる
目次

ブログのテーマに CSS を書き足したのに、見た目が変わらないことがあります。 CSS詳細度チェッカーは、書いた指定がほかの指定に勝てるかを確かめるツールです。

セレクタを並べると、強い順と、その差がどこで付いたかが分かります。 CSS をまとめて貼れば、同じ指定が重なったときにどれが使われ、ほかがなぜ負けたかまで出ます。

「書いたのに変わらない」あるある 3 つ

ブログやお店のサイトの見た目を CSS で直していると、次のような食い違いが起きます。

  • テーマの設定画面の「追加 CSS」に書いた色が、テーマの色のまま変わらない
  • 強める指定を足して直ったのに、別のページでまた効かなくなった
  • 同じクラスの名前で書いた 2 つの指定のうち、片方だけが効く

どれも、書いた指定が「ほかの指定に負けている」ときに起きます。 負けた理由が分からないまま強める指定を重ねると、次に直すときがさらに大変になります。

なぜ書いた指定が負けるのか

CSS では、同じ部分の同じ見た目に指定が 2 つ当たると、決まった順で 1 つだけが選ばれます。 その順の 1 つが、セレクタの強さを数えた「詳細度」です。

詳細度は、ID の数、クラスなどの数、要素の名前などの数の 3 つで比べます。 左の数が 1 つでも多いほうが勝つので、ID 1 つは、クラスをいくつ並べても追い越せません。

ただし、詳細度より先に比べるものが 3 つあります。 !important の有無、HTML の style 属性、レイヤーの順番です。 この順の詳しい説明は「CSSが効かない原因の確かめ方」にまとめました。

CSS詳細度チェッカーの使い方

1. セレクタを 1 行に 1 つ書く

「セレクタを比べる」の欄に、比べたいセレクタを 1 行に 1 つ書きます。 「例を入れる」を押すと、数え方を間違えやすい 6 つが入ります。

セレクタを比べる欄に、#nav a、クラスを 11 個並べたセレクタ、(#nav, .menu) a、(#nav, .menu) a、li(2 of .item) a、.menu a の 6 行が入っている

テーマの CSS から写すときは、{ から後ろを付けたまま貼っても読めます。 セレクタの部分だけを取り出して比べます。

2. 勝つ順と決め手を読む

書いた行が、強い順に並びます。 右の 3 つの数が詳細度で、下に「ID 1 / クラスなど 0 / 型など 1」のように中身が添えてあります。

勝つ順の表。1 位 (#nav, .menu) a と 2 位 #nav a がどちらも (1, 0, 1)、3 位のクラス 11 個のセレクタが (0, 11, 0)、6 位の (#nav, .menu) a が (0, 0, 1) と並び、下に 1 位と 2 位は同じ詳細度なので後に書いた 3 行目が勝つと書かれている

例では、ID が 1 つの #nav a が、クラス 11 個のセレクタより上に来ます。 1 位と 2 位は同じ (1, 0, 1) なので、後に書いた 3 行目が勝つと書かれます。

3. 部品ごとの内訳を見る

下には、行ごとのカードが並びます。 部品ごとに、どの数に何個足したかと、その理由が出ます。

(#nav, .menu) a のカード。(#nav, .menu) の行に (1, 0, 0) と、引数のうち #nav がいちばん高いので、それに置き換わると書かれ、a の行は型セレクタで C に 1 と書かれている

:is() のかっこの中は、いちばん強い #nav の強さに置き換わります。 同じ中身でも :where() で包むと 0 になるので、あとから上書きしやすくなります。

4. CSS を貼って、使われる指定を調べる

上の「CSS を貼って勝つ宣言を調べる」に切り替えると、CSS をまとめて貼れます。 同じ見た目の指定が 2 つ以上あると、使われる指定と、ほかが負けた理由が並びます。

color のカード。使われるのは #submit の gray !important(レイヤー base)で、その下に負けとして、.button の navy !important はレイヤーで負けた、#submit.button の black と .button.primary の white と .button の #333 は勝った宣言の !important に負けた、と並んでいる

例では、後のレイヤーにある navy !important が負けています。 !important どうしでは、先に宣言したレイヤーが勝つためです。 詳細度がいちばん高い #submit.button の black も、!important が無いので負けます。

style 属性の欄に要素の style 属性の中身を入れると、それも並べて比べます。 例の padding: 12px は、ほかの padding すべてに勝ちます。

5. レイヤーの順番を確かめる

@layer を使った CSS では、結果の下にレイヤーの順番が出ます。

レイヤーの順番の一覧。通常の宣言は下ほど強く、!important の宣言は上ほど強くなると書かれ、1. base、2. components、3. レイヤーの外 と並んでいる

ふだんの指定は下ほど強く、!important の指定は上ほど強くなります。 順番を逆に覚えていないかを、ここで確かめられます。

書き間違いも知らせる

セレクタに全角の記号が混ざると、CSS は別のセレクタとして読みます。 たとえば全角の #nav は、ID ではなく要素の名前として数えられます。

375px の画面で、#nav a のカードに (0, 0, 2) と出ていて、下に、全角の「#」が入っているので ID の印として働かない、という注意が出ている

開いているブラウザが読めないセレクタや値にも、注意が付きます。 ブラウザが読めない指定は、勝ち負けに加わらずに捨てられるためです。

こんな場面で使える

  • テーマの「追加 CSS」に書いた色や余白が、テーマに負けている理由を探すとき
  • 引き継いだサイトの CSS で、どの指定が効いているかを確かめるとき
  • CSS を @layer で整理する前に、勝ち負けが変わらないかを比べるとき
  • 強める指定を足す前に、負けている理由が詳細度かどうかを確かめるとき

使用例

たとえば、ブログの見出しの色を変えたいライターがいるとします。 追加 CSS に .entry-title { color: navy; } と書きました。 色が変わらないので、テーマの CSS から見出しの指定を探して、自分の指定と一緒に貼ります。

テーマ側が .single .entry-header .entry-title と書いていれば、詳細度は (0, 3, 0) です。 自分の (0, 1, 0) は「詳細度で負けました」と出るので、まず詳細度をそろえればよいと分かります。 同じセレクタで書けば詳細度は同じになり、あとは書いた順(後に読み込まれたほう)で決まります。

安心して使えるポイント

貼ったセレクタと CSS は外部に送らず、ブラウザの中だけで読み取ります。 公開前のサイトの CSS でも、そのまま貼って試せます。

ただし、HTML は見ていないので、貼ったルールがすべて同じ部分に当たるとして比べます。 実際に当たっているかは、ブラウザの開発者ツールで確かめてください。

関連ツール

まとめ

効かない CSS は、多くの場合、ほかの指定に負けています。 負けた理由が詳細度なのか、それより手前の段なのかを先に確かめると、直す場所を 1 つに絞れます。

CSS詳細度チェッカーを開く

補足: 開発者の方へ

詳細度は Selectors Level 4 §15、勝ち負けは CSS Cascading Level 5 §6.1 の順で数えています。 :is() と :where() は寛容な選択子リストとして、読めない引数だけを捨てて数えます。

ブラウザが読めるかは、セレクタを CSSStyleSheet.insertRule、値を CSS.supports に聞きます。 CSS.supports('selector(...)') は :is() の中を寛容に読まないので、セレクタには使っていません。

期待値は Chromium 141 に答えさせて作りました。 開発者ツールのプロトコルが返す詳細度と、getComputedStyle で読んだ値とを突き合わせています。

#a, b { & c { color: blue; } } /* & c は (1, 0, 1) */
& { color: red; }              /* 親の無い & は (0, 0, 0) */

あわせて読みたい

同じテーマ・関連ツールの記事です。