!importantはもう使わない!CSSの優先順位をおさらいしよう
- 2014/07/16
- atsuko.a

先日の台風で梅雨が明けた気分になっていましたが、全然そんなことなかったです。
こんにちは、フロントエンドエンジニアのあつこです。
HTMLとCSSでお仕事をするようになって暫く経つのですが
未だにスタイル効かない、何故だ。。。→優先度が低かった!ってことがたまに起こります。
Sass等メタ言語を使ってると、コンパイル後の形を想像しにくくなるのですね(´・ω:;.:...
今日はそんな「CSSにおけるスタイルの適応の優先順位」についてまとめてみました。
もくじ
- 0.デモの準備
- 1.基本の優先順位
- 2.タイプセレクタとclassセレクタ
- 3.親要素と一緒に指定する
- 4.idセレクタとclassセレクタ
- 5.つまりどうゆうこと?
- 6.最終奥義!important宣言
- おまけ.IEのセレクタの限界のはなし
「ある程度なら知ってるよ!」って方は5.つまりどうゆうこと?から読んでもらえれば大丈夫かと思います(ΦωΦ)
0.デモの準備
こんなHTMLがあったとします
HTML
1 2 3 4 |
<div class="hogehoge"> <p id="piyopiyo" class="fugafuga">ここは何色になるでしょう?</p> </div> |
よくデモで使われるような、ありがちなやつですね。
さて、このpタグさんに色を付けたいと思います。
CSS.1
1 2 3 |
p { background: blue; } |
まぁ、こうなりますよね。
(pタグの大きさに関する記述は省いています)
また、これは
CSS.2
1 2 3 |
.fugafuga { background: blue; } |
CSS.3
1 2 3 |
#piyopiyo { background: blue; } |
と同じ結果です。
1.基本の優先順位
まず、スタイル内での優先順位を見てみましょう。
CSS.4
1 2 3 4 |
p { background: blue; background: red; } |
CSS.1と似ていますが、下に新しく背景の指定がされています。
これをブラウザで見ると、、、
背景は青ではなく赤になりました。
どうやら、後に書かれたものの方が優先度が高いようです。
(※ここで言う「後に書かれた」というのは時間的なものではなく、上から下へCSSを読んだ時に記述的に下になっているものということです)
今度は同じセレクタに対して違う記述をしてみましょう。
CSS.5
1 2 3 4 5 6 |
p { background: blue; } p { background: red; } |
こちらも背景は青ではなく赤になりました。
このことから、CSSには同じセレクタに対して異なるスタイルを当てた場合後のものが優先されるようです。
後のものに上書きされる感じでしょうかね(ΦωΦ)
2.タイプセレクタとclassセレクタ
前述のCSS.1のようにタグをセレクタに使用したものをタイプセレクタ、CSS.2のようにclassをセレクタに使用したものをclassセレクタと呼びます。
次に、この2つを比べてみましょう。
CSS.6
1 2 3 4 5 6 |
.fugafuga { background: blue; } p { background: red; } |
classセレクタには青、タイプセレクタには赤を指定しました。
CSS.4の例では記述が後のものが優先されたのですが今回はどうでしょうか。
背景は赤ではなく青になりました。
タイプセレクタとclassセレクタではclassセレクタが優先されるようです。
3.親要素と一緒に指定する
CSS.6の記述をちょっと変えてみます。
CSS.7
1 2 3 4 5 6 |
.fugafuga { background: blue; } .hogehoge p { background: red; } |
CSS.6では優先されなかったタイプセレクタの前に親要素のclassセレクタが入っています。
こちらはCSS.6と違って背景は赤になりました。
classセレクタと親要素+タイプセレクタでは親要素+タイプセレクタが優先されるようです。
4.idセレクタとclassセレクタ
タイトルから察せられるようにCSS.3のようにidをセレクタに使用したものをidセレクタと呼びます。
今度はidセレクタとclassセレクタを比べてみましょう。
CSS.8
1 2 3 4 5 6 |
#piyopiyo { background: green; } .fugafuga { background: blue; } |
今度はidセレクタに指定した緑になりました。
idセレクタとclassセレクタではidセレクタが優先されるようです。
5.つまりどうゆうこと?
今までの例をまとめるとこうなります。
- 後に書いたものが優先される
- タイプセレクタ<classセレクタ<親要素+タイプセレクタ<idセレクタ の順に優先される
これ、どうゆうことかと言うと対象を詳しく指定しているセレクタが優先されるということなのです。
そしてこの詳しさの度合いを示すものが決められています。(http://www.w3.org/TR/CSS21/cascade.html#specificity)
なにやら読んでみると、モゴモゴ付いてるセレクタとかにそれぞれ点数付けて、点数が高い方を優先しようぜ!ってことみたい(・ω・)
で、それぞれのセレクタの点数はこう決めるよ!ってなってます。
簡単に訳すとこう。
- style属性がある→a値=1
- id属性の数=b値
- id以外の属性+擬似クラスの数=c値
- 要素+擬似要素の数=d値
a~d値はそれぞれ、数字の千の位~一の位にあたります。
で、表にまとめました。
指定方法 | 例 | 点数 |
---|---|---|
全称セレクタ | * | 0 |
タイプセレクタ | p | 1 |
擬似要素 | :first-child | 1 |
擬似クラス | [type="text"] | 10 |
classセレクタ | .fugafuga | 10 |
idセレクタ | #piyopiyo | 100 |
要素に直書き | style="" | 1000 |
この表に倣ってCSS.7を計算すると、
CSS.7
1 2 3 4 5 6 |
.fugafuga { background: blue; } .hogehoge p { background: red; } |
.fugafugaは10点、.hogehoge pは10点と1点で合計11点
なので、.hogehoge pが優先されるんですね、納得(∩´∀`)∩
ちょっとややこしい例を考えてみましょう
CSS.9
1 2 3 4 5 6 7 8 |
/*style 1*/ div#sample p.sample span { background: green; } /*style 2*/ div#sample p span { background: blue; } |
style 1はdiv→1点、#sample→100点、p→1点、.sample→10点、span→1点 =113点
style 2はdiv→1点、#sample→100点、p→1点、span→1点 =103点
なので、style 1が優先されます。
点数の合計が同じ場合は基本的な優先順位通り後に書いたものが優先されます。
6.最終奥義!important宣言
さんざん優先順位がどうの、という話をしましたが実はほぼ全ての優先順位を吹っ飛ばす奥義が存在します。
それがこれ
CSS.10
1 2 3 4 5 6 7 8 9 |
#piyopiyo { background: green; } .fugafuga { background: blue; } p { background: red !important; } |
通常であれば、idセレクタの#piyopiyoが優先されて緑になるはずがpで指定されている赤になっています。
これが!important宣言です。
これを付けたスタイルはほぼ全ての優先順位をすっ飛ばして適応されます。
(!importantの記述がバッティングした等すると、意図しない適応がされる場合があります)
が、優先順位のしくみを理解していたらあまり必要ないと思います。
あくまで本当にどうしようもない時の奥義として取っておいてください。
予期せずスタイルが適応されない事故とかが簡単に起こります、まじで。
!important宣言が付いてるばっかりに適応されず、すごく回りくどい記述をしなければいけなかったり、時には古いスタイルのリファクタを強いられたりします。
なのでなるべく使わないようにしましょう:(;゙゚'ω゚'):
おまけ.IEのセレクタの限界のはなし
私は今のところハマったことがないのですが、IE9以下にはCSSのセレクタの個数に制限があるようです。
1つのCSSファイル内に4,096個以上のセレクタが記載されていると超過分のスタイルは無視されてしまうそうです。
こわい。
IE10では修正されているようなのですが、大きなサービス等を扱う際には注意が必要ですね。
Sass等を使ってると、結構ナチュラルにセレクタが増えるので生成されたCSSを開けてみたらセレクタ祭りだった、とか結構あります。(よくない)
それでは今回はこのへんで(ΦωΦ)