さて、唐突にはじまりましたが「100年後も崩れない CSS 勉強会」、きょうは詳細度についてお話しします!
あっ 崩れてる!
…っていうのは CSS あるあるだと思うんですけど、スタイルシートを書いているときはきちんと表示できてても、あとから見るとあれ?おかしくない?みたいなこと、よくありませんか?
なんでスタイルが崩れてしまうんでしょうか。そのことを考えるために、逆になんでスタイルって「当たる」のか、というところを改めて見てみようと思います。
CSS には書かれたスタイルを適用する優先順位があって、まず1番目に上から順番に「当てる」というのと、その次に詳細度という順番によって「当てる」という、ふたつのルールがあります。
まずは、上から順番に「当たる」ことについて見てみます。
GMO Pepabo, Inc. とだけ書かれた div 要素があって、class という名前の class が指定されています。この class をセレクタにして、ふたつのスタイルシートが書かれています。このように CSS が書かれているとき、いったい GMO Pepabo, Inc. は何色になるのでしょうか。
ブラウザは CSS を上から順番に解釈していくので、上から1行ずつ見ていくと…
ここで color: red;
が評価されて、GMO Pepabo, Inc. は赤色になります。
しかし、スタイルシートはここで終わりではありません。
さらに見ていくと…
ここで color: blue;
と書いてあるので、さきほどの color: red;
の指定が上書きされて、GMO Pepabo, Inc. は青色になります。
このように、上に書かれているスタイルより、下に書かれてあるスタイルのほうが優先される。これがスタイルが「当たる」優先順位のひとつです。
それでは、もうひとつのほうのルール、
詳細度が高い順番に「当たる」というルールを見ていきます。
詳細度とは聞き慣れない言葉ですが、CSS でスタイルを指定するときのセレクタの種類によって、実は優先順位が異なります。その優先する強さのレベルを、ここでは A〜D ランクで格付けしてみようと思います。
優先する強い順に並べてみると、このようになります。!important
や *
といったものは、指定しただけで最強になったり優先順位がまったくないものなので、それぞれ最強と最弱としてランキングに含めてみました…。
ID セレクタは B ランクなので、このようにスタイルを指定すると、このスタイルの優先順位は B が 1 ポイントというふうに考えます。
class セレクタで指定すれば、優先順位は C が 1 ポイントです。
複数のセレクタが同時に指定されているときは、優先順位は合算されます。このように ID と class を指定した場合は、B が 1 ポイント、C が 1 ポイントといった具合になります。
要素セレクタも加えてみれば、B が 1 ポイント、C が 1 ポイント、D が 1 ポイント。
CSS ではなく、HTML で div 要素の style 属性にスタイルを指定したなら、これは A が 1 ポイントとなり、いちばん優先順位が強くなります。
…というルールをふまえて、#id と .class が指定された div 要素に、ID セレクタでスタイルを指定したあとに class セレクタで同じプロパティのスタイルを指定してみました。このとき、いったい GMO Pepabo, Inc. は何色になるでしょうか?
答えは、赤色です。なぜなら、ID セレクタのほうが C より強い B レベルのポイントが 1 ポイントあるので、class セレクタのスタイルが下に書かれていたとしても、より優先順位が高いと判断されるからです。
じゃあ、ということで ID セレクタひとつのスタイルと、class セレクタを 10 個つなげたスタイルを書いてみました。このときは、いったい GMO Pepabo, Inc. は何色になるでしょうか。
これも、ID セレクタが優先されて赤色になります。10 進法みたいに桁が繰り上がるということはなく、C レベルの値がどれだけ高くても、B レベルで負けてしまうと優先順位は低いと見なされてしまうんですね。
だから、class セレクタのスタイルに ID セレクタを追加すれば、もちろん青色になります。
しかし、そのあとに class セレクタがたったひとつだとしても、!important
を指定したスタイルがあれば、そちらが最強になってしまいます。
いくら CSS で !important
を指定した最強スタイルも、HTML で style 属性にインラインで書かれた !important
を指定したスタイルがあれば、こちらが優先される!
これらの例は隣りあって書かれているので把握することができますが、書いている箇所が離れていたり、CSS ではなく HTML にまでファイルが分かれて書かれていれば、把握しきれません。優先順位を把握しながら壊れないようにスタイルを指定するには、スタイルの詳細度を揃える必要があります。だから、 !important
はしない。style 属性にスタイルを指定しない。ID セレクタ、要素セレクタでは指定しない。
じゃあどうするの!というと、原則的に class セレクタで指定しておくのはどうでしょうか。全部おなじ詳細度であれば、あとから書いたスタイルが優先されるというルールだけ意識すれば、優先順位を把握できるようになります。だから、何が影響しているのかわからなくなったり、意図せずスタイルが崩れるということも少なくなるのではないでしょうか…?
もちろん、CSS は詳細度のために書いているわけではありません。ID セレクタでスタイルを指定すれば、要素がページにひとつしかないことが伝わります。要素名をセレクタに指定してスタイルを指定すれば、わざわざ HTML で class を指定しなくてもスタイルが適用されますし、body.pepabo
と書けば body 要素に pepabo
という class が指定されたときだけスタイルを指定できます。自分以外の誰か、または半年後のすべてを忘れてしまった自分のためにも、伝わる CSS を書くべきなんです!!
というわけで、まとめです。class セレクタ最高!
さらに、class セレクタで指定しておくというのは、ほかの場所でも再利用できるというメリットもあります。次回は、いかに再利用しやすいように CSS を書くのかという、「コンポーネント」について考えていきたいと思います。
嘘かもしれないから、W3C の仕様書も読んでみよう!
- Selectors Level 3 - 9. Calculating a selector’s specificity
- Selectors Level 4 (Editor’s Draft) - 15. Calculating a selector’s specificity