59
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

この記事は『CSS設計完全ガイド』という書籍の内容を元に、実際のホームページを見ながらCSS設計にふれてみよう!という内容になっております。

前回は、コンポーネントがmarginなどのレイアウトに関わるスタイルを持ってしまうと使いまわすことが難しくなるため、マルチクラスで対応するという「BEM」の「Mix」という書き方をご紹介しました。

今回はそのマルチクラスにおけるもう1つのメリット「詳細度を一定に保つ」というテーマで、そもそも詳細度ってなに?というお話からしていきたいと思います。

前回の振り返り

前回の記事はこちら↓


最初に軽く前回のおさらいをしておきます。

メディアが複数並んでいるレイアウトで、そのメディアコンポーネント自体にmargin-bottomを指定せず、.service-mediaというクラスを付与して、それにmarginを担当させよう、というお話でした。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333738333232322f64316339373961622d313663372d396463342d656335372d6232646565656464336162662e706e67.png

詳細度について

マルチクラス設計によって、コンポーネントが使い回せるというメリットに加えて 「詳細度を一定に保つ」 というメリットも生まれます。

まずは詳細度について、実際にコードを見ながら理解していきたいと思います。

<p class="sample-text">サンプルテキスト</p>

例えばこのサンプルテキストにスタイルを当てたいとき、次のCSSはどちらが優先されるか、というのは「詳細度」で決まります。

.sample-text {
    color: blue;
}
p {
    color: red;
}

結論から言うと、この場合はcolor: blueが反映されます。

そもそもの前提として、CSSは上から順番に読み込まれてスタイルが反映されます。

この.sample-textpという2つのセレクターは、どちらもHTMLの「サンプルテキスト」を指しています。

そのため、先に書かれているcolor: blueが後に書かれているcolor: redによって打ち消され、最終的に赤色が反映されそうなものですが...画面上で文字は青色のままです。


開発者ツールで見るとこうなっています。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333738333232322f36383935653136312d623461312d313335372d656161382d6337313463393239643964392e706e67.png

開発者ツール上では、一見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が反映されます。

image.png

つまり、.wrapper pといった「〇〇の子要素の〇〇」というセレクターは詳細度が高い、ということです。

これを覚えておいてください。

マルチクラスで詳細度が保たれる

では詳細度についてわかってきたところで、もう1度前回のコードを見てみましょう。

先ほどの詳細度のお話で、この2つのコードの違いがわかるかと思います。

/* .companyの子要素の.mediaにスタイルを指定 */
.company .media {
    margin-bottom: 60px;
}

/* .company-mediaにスタイルを指定 */
.company-media {
    margin-bottom: 60px;
}

これは前者の方が詳細度が高い状態ですね。

では詳細度が高いと何が困るかといえば、先ほどのサンプルテキストの例で見たように後からスタイルを追加しても、詳細度が高い方が優先されてスタイルが思ったように効かないという事態が生じます。

image.png

これはCSSで非常によくあるケースです😭
CSSが長くなればなるほど、こうした問題は起きやすくなり、追加・変更の難易度が上がっていきます。

では、マルチクラスの場合はどうだったでしょうか。

.media {
    /* margin-bottomの指定は不要 */
}

.service-media {
    margin-bottom: 30px;
}

.company-media {
    margin-bottom: 60px;
}

セレクターはどれもズバリそのクラスを指定していることがわかります。

.service .media.company .mediaといった指定が無くなるため、この中で詳細度の優劣はありません。

このように詳細度が一定であれば後から追加・変更があってもすぐに対応が可能になります。

おわりに

補足になりますが、「〇〇の子要素」という入れ子のセレクターを使うのはやめましょうということではなく、不必要にそういった指定が増えてくると思ったようにスタイルが当たらないことがあるよ、というお話になります。

また、案件によってはスタイルの衝突を避けるために、<span>から<p>から全てのHTMLタグにクラスを振るケースもありますので、詳細度については多少気を遣っておいて損はないでしょう。

「このセレクターって詳細度高くなってないかな」「こういう書き方もできそう」と少し考えるだけで、CSS設計の力が付いてくると思います。

参考

59
34
2

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
59
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?