5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CSS優先度のちょっと細かい話 !importantから継承まで

Posted at

CSSの優先度(簡易版)

  1. !important
  2. style属性
  3. 詳細度
    1. ID セレクター(#example など)
    2. クラスセレクター(.example など)、属性セレクター([type="radio"] など)、擬似クラス(:hover など)
    3. 要素型セレクター(h1 など)と擬似要素(::before など)
    4. 全称セレクター(*)(詳細度なし)
    5. より後にある定義
  4. 祖先からの継承

!important

!importantをつけたルールは優先されます
とても強いルールなので安易につけることは非推奨とされていますが、使い所を抑えておけばとても便利です

div { color: red !important; } /* こちらが適用される */
.class { color: blue; }

style属性(インラインスタイル)

要素に直接スタイルを適用できる属性です
外部のスタイルを上書きするため後述する詳細度からも一弾飛び抜けて優先されます

<div style="color: blue;"><!-- こちらが適用される -->
  text
</div>

詳細度(詳細度アルゴリズム)

一般的なCSSセレクターによって適用される優先度です
ざっくりいうとより具体的な指定がされているルールが適用されます

これにもちゃんと計算方法があります


まずセレクターは種類ごとにランク分けされており、どれがより詳細であるかが決まっています

詳細度が高い順 セレクター種類 備考
1 ID セレクター #example など
2 クラスセレクター、属性セレクター、擬似クラス .example、[type="radio"]、:hover など
3 要素型セレクター、擬似要素 h1、::before など
4 全称セレクター * 詳細度なし

例えば以下のようにIDセレクターを使ったルールがある場合、クラスセレクターより詳細度が高いためIDのほうが適用されます

#id { color: red; } /* こちらが適用される */
.class { color: blue; }

そして同ランクの場合はより該当するセレクターが多いほうが優先されます

.parent .child { color: red; } /* こちらが適用される クラスセレクター × 2 */
.child { color: blue; } /* クラスセレクター × 1 */

セレクターの数まで一致している場合は後に定義されたルールが適用されます

.parent1 .child { color: red; }
.parent2 .child { color: blue; } /* こちらが適用される */

祖先からの継承

最後に一部のCSSは祖先要素から値を継承します。
だいたい文字に関わるCSSは継承されているようです。

<div class="parent">
  <div>
    Child
  </div>
</div>
.parent { color: red; }

どっちが強い?


問1

<h1 id="id1" class="c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11">
  COLOR
</h1>
#id1 { color: red; }
.c1.c2.c3.c4.c5.c6.c7.c8.c9.c10.c11 { color: blue; }

問1答え

赤色

image.png

詳細度はID セレクターのほうがより優先度が高い仕様なので、クラスをいくらつけたところでID指定には勝てません。

他のサイトだとIDは100点、classは10点という点数換算で詳細度を紹介しているところがありますがあれは正確ではありません。


問2

<h1 id="id1" style="color: gray !important;">
  COLOR
</h1>
#id1 { color: red !important; }

問2答え

灰色

image.png

style属性、idセレクターのどちらにも!importantがついているので次に優先度の高いstyle属性のほうが優先される

多分これが一番優先度が高いと思います


問3

<h1 id="parent">
  <div class="child">
    <div>
      COLOR
    </div>
  </div>
</h1>
* { color: blue; }
.child { color: green; }
#parent { color: red; }

問3答え

青色

image.png

COLORの文字列は#parentの直下でも、.childの直下でもない。
全称セレクター(*)は詳細度の範囲で、継承よりも優先度が高くなる


もうちょっと深堀りした話

CSS宣言のオリジン

CSSの宣言は大きく3つの起源に分けられる

  • ユーザーエージェントスタイルシート
    • ブラウザによって定義されたスタイル。いわゆるデフォルトスタイル
  • 作成者スタイルシート
    • ページの作成者によって定義されたスタイル。我々エンジニアがいじっているCSSはこれ
  • ユーザースタイルシート
    • ユーザーによって定義されたスタイル

カスケードアルゴリズムと詳細度アルゴリズム

CSSの評価は大きく2つのアルゴリズムによって行われている

適用順序 アルゴリズム 内容
1 カスケードアルゴリズム CSSの起源と重要度による適用
2 詳細度アルゴリズム id, class, 要素

カスケードアルゴリズムでは以下のような優先度になっている。

優先度 起源 重要度
1 ユーザーエージェントスタイルシート !important
2 ユーザースタイルシート !important
3 作成者スタイルシート !important 普段開発で意識するのはここ
4 作成者スタイルシート 通常 普段開発で意識するのはここ
5 ユーザースタイルシート 通常
6 ユーザーエージェントスタイルシート 通常
※アニメーションの考慮は除く

!importantが優先されるのはそもそも評価タイミングが違うから!


これらのルールを踏まえた上で、スタイル定義の留意点

  • 基本的にはclassによってスタイルをつける
    目的別にclassを用意しておけば変更も流用もしやすい。
    classじゃ不都合なときに他のセレクターやstyle属性など適切なものを使えば良い

  • !importantはこれ以上のスタイルの変更が加わらない箇所でなら使ってよし
    特に極々限定的なデザインのカスタマイズをする必要があるときに詳細度で頑張らなくて良い
    逆にライブラリや汎用的なコンポーネント、詳細度の低いルールで!importantをつけてはいけない

それほど特別なことは無いです。
自分は今までもやっていたけど、仕様を調べたことでより納得感がましたと思います。


CSS優先度のデバッグ

たいていのブラウザはF12キーを押すとdeveloper toolsが開きます。その要素(Element)タブでCSSを確認できます。

適当な要素をクリックするとその要素に関連するCSSルールがすべて表示されます。
その要素は詳細度の高い順に並んでいるため、上にあるCSSが適用されるとおぼえておくと良いでしょう

image.png

他にも上書きされたスタイル、ユーザーエージェントのスタイル、継承されたスタイいるなどの情報ものっています。

image.png

計算済み(Computed)には最終的に適用されたスタイルの一覧が表示されます。
分類する(Grouping)チェックを入れると関心の近いものが集まって表示されるのでおすすめです。
特定のプロパティを開くと関連するルールもすべて表示されます。(こちらも詳細度順)

image.png

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?