その他

CSS 詳細度について

この記事は約5分で読めます。

はじめに

レイアウトを修正するためにCSSをいじることってあると思うのですが
その時に、「CSSを修正したはずなのに、思った通りにレイアウトが修正できていない😭」
という経験をされた事ってありませんか?

現案件で自分もそのような経験を何度もしてしまい、同じプロジェクトメンバーに質問しまくりました。その時に、あるメンバーから詳細度について教えていただきました。
良い機会なので詳細度について自分なりに調べたことをrambleに投稿しようと思い
今回の記事を書くことに決めました、

詳細度とは

詳細度とは、スタイルがどのHTML要素に適用されるかを決定するためのルールです。異なるCSSルールが同じ要素に適用される場合、どのルールが優先されるかを決める重要な概念です。

どのようにして優先順位をつけるか

詳細度は、基本的に「点数制」と考えることができます。ルールに含まれるセレクタの種類に応じて、そのルールには特定の点数が与えられます。点数が高いルールほど優先度が高くなります。
セレクタの順位としては以下のようになります。

セレクタ名詳細度のポイント
【階層1】idセレクタ(例 #header)100
【階層2】クラスセレクタ(例 .menu)、属性セレクタ(例 [type=”text”])
     擬似クラス(例 :hover)
10
【階層3】タイプセレクター(例 div)、疑似要素(例 :after)1
【階層4】ユニバーサルセレクタ(例 *)、コンビネータ(例 ` ` , `>` ,`+` ,` ~`)
     否定擬似クラス(例 :not())
0

計算方法はセレクタのポイントの単純な足し算です。
その合計値が大きければ大きいほど、優先度が高くなります。ポイントを多くとったほうが勝ちです。

ただし一点注意事項としては、階層が下のセレクタがどれだけ集まってポイントを稼いでも上の階層のセレクタには勝つことはできません。

例えば、以下の場合
クラスセレクタ150ポイント VS idセレクタ100ポイント

階層が下のセレクタがどれだけ集まってポイントを稼いでも上の階層のセレクタには
勝てない規則により
idセレクタ100ポイント > クラスセレクタ150ポイント
という優先度になります。

具体例 その1

//タイプセレクタ
div {
  background-color: black;
}

//クラスセレクタ
.green {
  background-color: green;
}

//タイプセレクタ + クラスセレクタ
div.yellow {
  background-color: yellow;
}

①divセレクタ
タイプセレクタ1つなので、1点

②.greenセレクタ
クラスセレクタ1つなので、10点

③div.yellowセレクタ
タイプセレクタ1つ + クラスセレクタ1つなので、11点

のようなポイントになります。この場合、ポイントの高いパターン3が優先されることになります。

ブラウザで確認してみると、以下のようになります。

具体例 その2

//idセレクタ
#hoge {
  background-color: red;
  color:white;
}

//クラスセレクタ
.hoge1.hoge2.hoge3.hoge4.hoge5.hoge6.hoge7.hoge8.hoge9.hoge10.hoge11 {
  background-color: blue;
  color:white;
}
<div  id="hoge" class="hoge1 hoge2 hoge3 hoge4 hoge5 hoge6 hoge7 hoge8 hoge9 hoge10 hoge11">
 <h1>hoge</h1>
</div>

①idセレクタ
idセレクタ1つなので、100点

②クラスセレクタ
クラスセレクタ11個なので、110点

この場合、階層が下のセレクタがどれだけ集まってポイントを稼いでも上の階層のセレクタには
勝てない規則により
パターン1が優先されることになります。

ブラウザで確認してみると、以下のようになります。

セレクタの詳細度とは別の優先度

CSSのスタイル適用には、セレクタの詳細度とは異なる形式の優先度も存在します。これはポイント制に基づかない強制力が特徴で、詳細度よりも強い影響力を持ってスタイルが適用されます。

インラインstyle

インラインstyleはセレクタの詳細度とは別の仕様で、スタイルシートのスタイルを上書きします。
そのため優先度が高いです。

スタイルシートに同じ要素に対してのスタイルが書かれていたとしてもすべてが無効になり、こちらが適用されます。(後述の!importantは除く)

//インラインstyle
<div  id="hoge" class="hoge" style="color:black; background-color: orange;">
   <h1>hoge</h1>
</div>

ブラウザで確認してみると、以下のようになります。

!important

!importantもインラインstyleセレクタの詳細度とは別の仕様で、他のあらゆるプロパティを強制的に
上書きするので、最も優先度が高いです。

同じプロパティに!importantが記載された場合は、セレクタの詳細度が適用されます。

先ほど具体例1で記載したコードで試してみると、一番優先度の低かったパターン1が適用されます。
!importantを使用すると、詳細度が強すぎるがゆえの問題が起きてしまうので使用を控えることを
オススメいたします。

//タイプセレクタ
div {
  background-color: black!important; //!importantを追記
}

//クラスセレクタ
.green {
  background-color: green;
}

//タイプセレクタ + クラスセレクタ
div.yellow {
  background-color: yellow;
}

ブラウザで確認してみると、以下のようになります。

最後に

詳細度について理解していれば、実装時だけでなく、既存サイトのデバッグやChromeの開発者ツールを使用してコードを確認する際にも非常に役立ちます。このことを頭の片隅に留めておいていただけると幸いです。

参考サイト

CSSセレクタ詳細度の理解を深める

【CSS】詳細度を知ろう!スタイルの優先度について簡単にまとめてみた!

CSSの詳細度を学ぼう