ホームページを眺めながらCSS設計について学ぼう【詳細度編】

## はじめに
この記事は[『CSS設計完全ガイド』](https://www.amazon.co.jp/CSS%E8%A8%AD%E8%A8%88%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E8%A9%B3%E7%B4%B0%E8%A7%A3%E8%AA%AC-%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E9%9B%86-%E5%8D%8A%E7%94%B0-%E6%83%87%E5%BF%97/dp/429711173X)という書籍の内容を元に、実際のホームページを見ながらCSS設計にふれてみよう！という内容になっております。

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

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

## 前回の振り返り
:::note info
前回の記事はこちら↓
:::
https://qiita.com/shimamoooon/items/e174f41fb1fa9f637a03

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

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

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333738333232322f64316339373961622d313663372d396463342d656335372d6232646565656464336162662e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783222/80d7a694-9e9a-ac1c-ec6d-a8150c2ed09e.png)


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

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

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

例えばこのサンプルテキストにスタイルを当てたいとき、次のCSSはどちらが優先されるか、というのは「詳細度」で決まります。
```css
.sample-text {
    color: blue;
}
p {
    color: red;
}
```
結論から言うと、この場合は`color: blue`が反映されます。

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

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

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

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

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333738333232322f36383935653136312d623461312d313335372d656161382d6337313463393239643964392e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783222/a41fe7fd-838d-ef8b-d26f-34116bf9a64b.png)


開発者ツール上では、一見`color: blue`が打ち消されています。

これは何が起きているかというと、**HTMLタグよりクラスで指定した方が詳細度が高い**ため、`color: blue`の方の指定が反映されているんですね。

CSSでは上記のようなHTMLタグとクラス以外にも、IDや擬似要素などさまざまな要素をセレクターとして指定できます。
その中で優先度が決まっており、同じ対象に対してスタイルを指定すると、その優先度が高い方が画面に反映されます。

https://developer.mozilla.org/ja/docs/Web/CSS/Specificity


では、次のケースではどうでしょう。
```html
<div class="wrapper">
  <p class="sample-text">サンプルテキスト</p>
</div>
```
```css
.wrapper p {
  color: green;
}
.sample-text {
  color: blue;
}
p {
  color: red;
}
```
先ほどのサンプルテキストのをdivタグで囲んで、CSSにセレクターを追加しました。

もうだいたいお分かりかと思いますが、これは最初に指定した`color: green`が反映されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783222/7a29edde-4573-db73-abc7-a2b2f99fe328.png)

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

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

## マルチクラスで詳細度が保たれる
では詳細度についてわかってきたところで、もう１度前回のコードを見てみましょう。

先ほどの詳細度のお話で、この２つのコードの違いがわかるかと思います。
```css
/* .companyの子要素の.mediaにスタイルを指定 */
.company .media {
    margin-bottom: 60px;
}

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783222/52d95a23-3b28-f295-fccf-d6b8844b4e06.png)

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

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

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

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

.company-media {
    margin-bottom: 60px;
}
```
セレクターはどれもズバリそのクラスを指定していることがわかります。

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

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

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

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

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

## 参考
- [CSS設計完全ガイド](https://www.amazon.co.jp/CSS%E8%A8%AD%E8%A8%88%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E8%A9%B3%E7%B4%B0%E8%A7%A3%E8%AA%AC-%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E9%9B%86-%E5%8D%8A%E7%94%B0-%E6%83%87%E5%BF%97/dp/429711173X)
- [詳細度](https://developer.mozilla.org/ja/docs/Web/CSS/Specificity)