もくじ
大雑把にいえば
CSSの優先順位は,大雑把にいえば,何に対してスタイルを定義するかで決まる。こんな感じに。
!important指定 > HTMLのstyle属性 > id > class > HTMLタグ
!important指定の例↓
div {
background-color: red !important;
}
HTMLのstyle属性の例↓
<div style="background-color: red;">
あばばば
</div>
idの例↓
#slash-mochi {
background-color: red;
}
classの例↓
.slash-mochi {
background-color: red;
}
HTMLタグの例↓
div {
background-color: red;
}
もっと詳しくいうと
CSSのスタイルは,次のようにidやclassなどを組み合わせた「セレクタ」で画面のどの要素に適用するのかを決める。
#slash-mochi .mochi-button span /* ←これがセレクタ */ {
background-color: red;
width: 100px;
}
このセレクタに,id,class,HTMLタグがそれぞれ何回出現するかによって,優先順位が決まる。
この回数をカウントするカウンターを4つ用意する。
それぞれ,
- HTMLのstyle属性に直接スタイルを指定した回数(0か1)
- idの出現回数
- classの出現回数
- HTMLタグの出現回数
を数えるカウンターとなっている。
このカウンターで数えた回数が2つのセレクタで同じ場合は,後から定義されたセレクタのスタイルで上書きされる。
回数が異なる場合は,以下の要領で優先順位が決定される。
例1
先ほどのセレクタの例をもう一度見てみよう。
#slash-mochi .mochi-button span {
background-color: red;
width: 100px;
}
この例ではHTMLのstyle属性にスタイルが定義されていない(最初のカウンターは0回)とする。
idが1回,classが1回,HTMLタグが1回出現するので,このときのカウンターの回数を (0, 1, 1, 1) と表現しよう。
次の場合はどうか。
#slash-mochi div.mochi-button span {
background-color: blue;
}
これはHTMLタグが2回出現するのでカウンターは (0, 1, 1, 2) となる。
(0, 1, 1, 1) と (0, 1, 1, 2) の2つのセレクタが競合するとき,どちらのスタイルを適用するかを決めるためにカウンタの数が左から順に比較される。
最も左のカウントは2つとも0なので同点。
左から2番目のカウントは2つとも1なので同点。
3番目のカウントは2つとも1なので同点。
最後のカウントは,前者は1,後者は2なので,後者の方が大きい。
よって,後者のセレクタで指定したスタイルが優先される。
後者のセレクタでは,background-colorのみ指定しているので,上書きするスタイルはbackground-colorのみとなる。今回の例ではwidthは前者のものが適用される。
例2
もう一つ例を挙げよう。
#slash-mochi .mochi-button.mochi-click-animation span {
background-color: red;
}
#slash-mochi button.mochi-button div span {
background-color: blue;
}
前者のカウンタは (0, 1, 2, 1) ,後者は (0, 1, 1, 3) である。
カウンタの数を左から順に比較していく。
最も左はともに0で同点。
左から2番目はともに1で同点。
3番目は前者が2,後者が1で,前者の方が大きい。
よって,前者のセレクタで指定したスタイルが優先される。
3番目で比較が終了するため,4番目のカウンタは考慮されない。
!important指定について
一つ注意すべきなのは,!important指定されたスタイルがある場合,上記の優先順位に関係なく,最優先で適用されるということだ。他の!important指定されたスタイルが競合し,かつカウンタもより大きいものでない限り,上書きもされない。
!importantの使いどころ
一般に,!importantでスタイル指定することは次の理由から避けるべきとされている。
- 「なぜかスタイルの上書きができない」という問題が後から起きる。最初から「!important指定してスタイルが適用されている」という想定で人が書いたCSSをメンテナンスする技術者はほぼいないと思う。
- スタイルの上書きが後から必要となった場合に上書きできるセレクタが書きにくくなる。
- 結局 !important指定をして上書きすることになり,やがて !important が頻発するようになり,!important を使わなかった場合と同じ状況になる。意味ねー。
要するに保守(メンテナンス)が非常に面倒になるのだ。
できる限り使わないに越したことはない。
次のようにやむを得ない場合に限り使うべきだろう。
- サードパーティが作ったライブラリを使っている状況で,そのライブラリ内で !important指定をしているスタイルがあり,それを上書きする必要がある場合。
- サードパーティが作ったライブラリを使っている状況で,そのライブラリ内のJavaScriptコードが動的にHTMLのstyle属性にスタイルを当て込んでいるが,そのスタイルを上書きする必要がある場合。
よほどの事情がない限り,自分たちが作っているコード内では !important は不要のはずだ。