はじめに
この記事は『CSS設計完全ガイド』という書籍の内容を元に、実際のホームページを見ながらCSS設計にふれてみよう!という内容になっております。
前回は、コンポーネントがmarginなどのレイアウトに関わるスタイルを持ってしまうと使いまわすことが難しくなるため、マルチクラスで対応するという「BEM」の「Mix」という書き方をご紹介しました。
今回はそのマルチクラスにおけるもう1つのメリット「詳細度を一定に保つ」というテーマで、そもそも詳細度ってなに?というお話からしていきたいと思います。
前回の振り返り
前回の記事はこちら↓
最初に軽く前回のおさらいをしておきます。
メディアが複数並んでいるレイアウトで、そのメディアコンポーネント自体にmargin-bottom
を指定せず、.service-media
というクラスを付与して、それにmarginを担当させよう、というお話でした。
詳細度について
マルチクラス設計によって、コンポーネントが使い回せるというメリットに加えて 「詳細度を一定に保つ」 というメリットも生まれます。
まずは詳細度について、実際にコードを見ながら理解していきたいと思います。
<p class="sample-text">サンプルテキスト</p>
例えばこのサンプルテキストにスタイルを当てたいとき、次のCSSはどちらが優先されるか、というのは「詳細度」で決まります。
.sample-text {
color: blue;
}
p {
color: red;
}
結論から言うと、この場合はcolor: blue
が反映されます。
そもそもの前提として、CSSは上から順番に読み込まれてスタイルが反映されます。
この.sample-text
とp
という2つのセレクターは、どちらもHTMLの「サンプルテキスト」を指しています。
そのため、先に書かれているcolor: blue
が後に書かれているcolor: red
によって打ち消され、最終的に赤色が反映されそうなものですが...画面上で文字は青色のままです。
開発者ツールで見るとこうなっています。
開発者ツール上では、一見color: blue
が打ち消されています。
これは何が起きているかというと、HTMLタグよりクラスで指定した方が詳細度が高いため、color: blue
の方の指定が反映されているんですね。
CSSでは上記のようなHTMLタグとクラス以外にも、IDや擬似要素などさまざまな要素をセレクターとして指定できます。
その中で優先度が決まっており、同じ対象に対してスタイルを指定すると、その優先度が高い方が画面に反映されます。
では、次のケースではどうでしょう。
<div class="wrapper">
<p class="sample-text">サンプルテキスト</p>
</div>
.wrapper p {
color: green;
}
.sample-text {
color: blue;
}
p {
color: red;
}
先ほどのサンプルテキストのをdivタグで囲んで、CSSにセレクターを追加しました。
もうだいたいお分かりかと思いますが、これは最初に指定したcolor: green
が反映されます。
つまり、.wrapper p
といった「〇〇の子要素の〇〇」というセレクターは詳細度が高い、ということです。
これを覚えておいてください。
マルチクラスで詳細度が保たれる
では詳細度についてわかってきたところで、もう1度前回のコードを見てみましょう。
先ほどの詳細度のお話で、この2つのコードの違いがわかるかと思います。
/* .companyの子要素の.mediaにスタイルを指定 */
.company .media {
margin-bottom: 60px;
}
/* .company-mediaにスタイルを指定 */
.company-media {
margin-bottom: 60px;
}
これは前者の方が詳細度が高い状態ですね。
では詳細度が高いと何が困るかといえば、先ほどのサンプルテキストの例で見たように後からスタイルを追加しても、詳細度が高い方が優先されてスタイルが思ったように効かないという事態が生じます。
これはCSSで非常によくあるケースです😭
CSSが長くなればなるほど、こうした問題は起きやすくなり、追加・変更の難易度が上がっていきます。
では、マルチクラスの場合はどうだったでしょうか。
.media {
/* margin-bottomの指定は不要 */
}
.service-media {
margin-bottom: 30px;
}
.company-media {
margin-bottom: 60px;
}
セレクターはどれもズバリそのクラスを指定していることがわかります。
.service .media
や.company .media
といった指定が無くなるため、この中で詳細度の優劣はありません。
このように詳細度が一定であれば後から追加・変更があってもすぐに対応が可能になります。
おわりに
補足になりますが、「〇〇の子要素」という入れ子のセレクターを使うのはやめましょうということではなく、不必要にそういった指定が増えてくると思ったようにスタイルが当たらないことがあるよ、というお話になります。
また、案件によってはスタイルの衝突を避けるために、<span>
から<p>
から全てのHTMLタグにクラスを振るケースもありますので、詳細度については多少気を遣っておいて損はないでしょう。
「このセレクターって詳細度高くなってないかな」「こういう書き方もできそう」と少し考えるだけで、CSS設計の力が付いてくると思います。