詳細度 (Specificity) は、どの CSS プロパティが要素に最も関係があるか、すなわち適用されるかをブラウザーが決定する手段です。詳細度は様々な組み合わせの CSS セレクターで構成される一致規則に基づいています。

詳細度はどのように計算されるのか

詳細度は CSS 宣言が適用される際の重みであり、一致するセレクターそれぞれの種類の数によって特定されます。複数の宣言が同じ詳細度であれば、 CSS の中で最後に宣言されたものが要素に適用されます。詳細度は同じ要素に対して複数の宣言が行われている場合のみ適用されます。 CSS の規則として、直接対象となった要素は要素が祖先から継承した規則よりも常に優先されます。

メモ: 文書ツリー内における要素の近接性は、詳細度には影響を与えません。

詳細度の序列(昇順)

以下のリストは、セレクターを詳細度の小さな順に並べたものです。

  1. 型セレクター (例えば h1) と 疑似要素 (例えば ::before)
  2. クラスセレクター (例えば .example)、属性セレクター (例えば [type="radio"])、疑似クラス (例えば :hover)
  3. ID セレクター (例えば #example)

全称セレクター (*), 結合子 (+, >, ~, ' ') 及び否定疑似クラス (:not()) は詳細度に影響を与えません。 (但し、 :not()中で宣言されたセレクターは影響を与えます。)

要素に追加されたインラインスタイル (例えば style="font-weight:bold") は、常に外部スタイルシートの中のスタイルを上書きしますので、最も高い詳細度を持っていると考えることもできます。

!important の例外

!important 規則がスタイル宣言で使われたとき、それが宣言リストのどこであっても、この宣言は CSS 内で作られたその他の宣言を上書きします。技術的には !important は詳細度とは無関係ですが、直接作用します。しかし、スタイルの自然のカスケードを破壊するためデバッグが難しくなるので、 !important を使用することは悪い習慣であり、使用を避けるべきです。同じ要素に二つの競合する宣言が !important 規則付きで適用された場合、より高い詳細度の宣言が適用されます。

いくつかの経験則

  • !important を考える前に、常に詳細度を使用する方法を探しましょう。
  • ページ固有の CSS が外部の CSS (ブートストラップや正規化 CSS などの外部ライブラリなど) を上書きする場合のみ!important を使用しましょう。
  • プラグインやマッシュアップを書いている時は、 !important決して使わないようにしましょう。
  • サイト全体の CSS で !important決して使わないようにしましょう。

!important を使用する代わりに、できることがあります。

  1. CSS のカスケードプロパティをもっと使うようにする
  2. もっと詳細な規則を使う。規則の選択時に要素の前に1つまたは複数の要素を示すと、詳細度が上がり、より優先度が高くなります。

    <div id="test">
      <span>Text</span>
    </div>
    
    div#test span { color: green; }
    div span { color: blue; }
    span { color: red; }
  3. (2)のナンセンスの特殊なケースとして、何も指定する必要がない場合には、単純にセレクターを複製して詳細度を高めることができます。

順番に関係なく、テキストは最も詳細度の高い規則である緑になります。 (また、順番に関係なく、青のルールは赤のルールを上書きします。)

利用するべき場合

A) 第一のシナリオ:

  1. サイト全体の視覚的な面を設定したグローバルの CSS ファイルがある。
  2. 要素のインラインスタイルを使用する。これはとても悪い習慣だと見なされている。

この場合、グローバルの CSS に特定のスタイルを important を付けて設定しているので、要素に直接インラインスタイルを設定しています。

実世界の例として、一部の jQuery プラグイン がインラインスタイルを使用して下手に書かれています。

B) 第二のシナリオ

#someElement p {
  color: blue;
}

p.awesome {
  color: red;
}

#someElement の中にある場合であっても、 awesome の段落を常に赤くするにはどうすればよいでしょうか。 !important がないと、第一の規則がより詳細度が高いので、第二の規則に勝ちます。

!important を上書きする方法

A) 単純に !important の付いた CSS 規則と、それにより高い詳細度のセレクターを与えるか (タグ、 id、 class のセレクターへの追加)、同じセレクターで既存の位置より後に CSS 規則を追加するかします。これが動作するのは、詳細度が同じであるとき、最後に定義された規則が勝つからです。

詳細度を高める例です。

table td    { height: 50px !important; }
.myTable td { height: 50px !important; }
#myTable td { height: 50px !important; }

B) または、既存の物の後に同じセレクターを追加します。

td { height: 50px !important; }

C) また、元の規則を書き換えて、どちらも !important を使用しないようにします。

詳しい情報は、以下の記事をご覧ください。

:not の例外

否定擬似クラスの :not は詳細度の計算では擬似クラスとは見なされません。しかし、否定擬似クラスの中に置かれたセレクターは、通常のセレクターのように計算されます。

以下の CSS を...

div.outer p {
  color: orange;
}
div:not(.outer) p {
  color: blueviolet;
}

以下の HTML に適用した場合...

<div class="outer">
  <p>This is in the outer div.</p>
  <div class="inner">
    <p>This text is in the inner div.</p>
  </div>
</div>

画面では、以下のように表示されるでしょう。

形ベースの詳細度

詳細度は、セレクタの形に基づきます。以下の場合、セレクタは ID を選択しているにもかかわらず、詳細度の決定アルゴリズムにおいて、それは属性として計算されます。

以下のスタイル宣言を...

*#foo {
  color: green;
}
*[id="foo"] {
  color: purple;
}

この HTML に対して適用すると...

<p id="foo">I am a sample text.</p>

このようになってしまうでしょう。

なぜなら、それは同じ要素に一致しますが、 ID セレクターがより高い詳細度をもっているからです。

文書ツリー内の近さの無視

以下のスタイル宣言と...

body h1 {
  color: green;
}
html h1 {
  color: purple;
}

以下の HTML で...

<html>
  <body>
    <h1>Here is a title!</h1>
  </body>
</html>

このように描画されるでしょう。

これは、二つの宣言が同じセレクター型数ですが、 html h1 セレクターが最後に宣言されているからです。

直接対象の要素と継承されたスタイル

直接対象となる要素のスタイル付けは、継承された規則の詳細度に関わらず、常に継承されたスタイルより優先されます。この CSS は ...

#parent {
  color: green;
}
h1 {
  color: purple;
}

... 以下の HTML と共に使用します ...

<html>
  <body id="parent">
    <h1>Here is a title!</h1>
  </body>
</html>

... 以下のように表示されます。

これは、 h1 セレクターが要素を具体的に対象としていますが、緑のセレクターは親から継承されているだけだからです。

関連情報

ドキュメントのタグと貢献者

このページの貢献者: mfuji09, yoshidax, ethertank, sii
最終更新者: mfuji09,