scss(css)のプロパティ適用の優先度をセルフ検証してみた

>どうもaono1234と申します。記事がいいなと思ったらtwitterのフォローもお待ちしております‼
https://twitter.com/takeshi_program

お疲れ様です❗❗
今日は`scss(css)`のプロパティ優先度についての検証記事となります。😄
拙い文章ですが、良かったらご覧ください❗❗

# 0.記事を書くきっかけ
`scss`ファイルでスタイル実装をしている際、コードを書いている場所やセレクタによっては反映されないということが何度もありました。
「時間を掛けたのに、実装できたのこれだけ？😥」というのが何日も続いたので優先度について深堀しました。

`scss`についてまだ把握不足感は否めませんがが、<b>【プロパティの優先度】</b>についてわかる所まで検証したので、共有させて頂きます。


# 1. はじめに
本記事は以下の読者が対象です。

- プログラミング初心者
- `css`を知っている人
- `scss`を知っている人

# 2. 先に結論
1. <b>基本優先度はセレクタの種類>セレクタの詳細度>コードが記載される箇所

2. <b>場合によっては`1.`のルールに当てはまらない場合がある

2. <b>`scss`を追加コーディングする際は既存コードの構造を把握した上で追加しよう


# 3. 優先度って何？
`html`構造が以下の場合、
```html:元ファイル
<div class = "test1" id = "test1">
  <div class = "test2" id = "test2">
    <p  class = "message" id = "message">hello world</p>
  </div>
</div>
```

`scss`を↓このように書いたとします。
```scss:example1
//スタイル1
.test2{
  .message{
    background-color: red;
  }
}

//スタイル2
.message{
  background-color: yellow;
}
```
`スタイル1`、`スタイル2`はどちらも`.message`クラスの背景色を変えるコードです。
さて、どちらのスタイルが適用されますか？
これを私は「優先度」と呼んでおります。

::: note warn
ちなみに、このコードは`スタイル1`が優先されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/757a3fb9-66fa-4f67-3dcf-dd4d7f08f159.png)
:::


# 3. 優先度を決めるファクター
どちらのプロパティの優先度が高いか、私の知る限り3つのファクターが存在していると考えます。
1. <b>セレクタの種類

2. <b>セレクタの詳細度

3. <b>コードが記載される箇所

それぞれ紹介します。

## 3.1セレクタの種類
「1.セレクタの種類」についてはこのWEBサイトに分かりやすく解説があったので参考にしてください。
>https://webst8.com/blog/css-selector-priority/

## 3.2セレクタの詳細度
`scss`では同じ`.message`にプロパティをあてることができため、
```scss:example1
//スタイル1
.test2{
  .message{
    background-color: red;
  }
}

//スタイル2
.message{
  background-color: yellow;
}
```
のような書き方ができます。
`スタイル1`は
<b>「`.test2`クラスの中の要素の`.message`クラスの`background-color`プロパティを`red`にしてね」👩

`スタイル2`は
<b>「`.message`クラスの`background-color`プロパティを`yellow`にしてね」👳‍♂️

という内容のコードです。
このコードの優先度は、より詳細に`.message`の場所を伝えてくれている`スタイル1`👩の方が高くなるため、`スタイル1`の`background-color`プロパティが適用されます。

## 3.3コードが記載されている箇所
この場合はどうでしょうか？
```scss:example2
//スタイル3
.message{
  background-color: red;
}
//スタイル4
.message{
  background-color: yellow;
}
```
どちらも、同じセレクタで詳細度も同じです。

基本的にプログラミングは上から順番に読み込まれます。
そのため、`スタイル3`も`スタイル4`もブラウザに読み込まれていますが、`スタイル3`が先に読み込まれ、その後`スタイル4`で上書きされている状態です。
したがって、この場合`スタイル4`のプロパティが優先されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/3f75a566-fb14-33a4-b222-efcf85d5e9ac.png)


::: note 
下記のように同じプロパティを指定しなければ、両方が適用されます。
```scss:example3
//スタイル5
.message{
  background-color: red;
}

//スタイル6
.message{
  // background-color: yellow;
  font-weight: 900;
}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/39091f32-fbcd-385f-0848-a2519b5f52fd.png)
:::


## 4.ファクターが複数重なった場合
前述した3つのファクターがそれぞれが重なった場合はどうなるでしょうか？
例えば、以下のような場合
```scss:example4
//スタイル7
//コードが記載される箇所（優先度：低）
//セレクタの詳細度（優先度：高）
//セレクタの種類（優先度：低）
.test2{
  .message{
    background-color: red;
  }
}

//スタイル8
//コードが記載される箇所（優先度：高）
//セレクタの詳細度（優先度：低）
//セレクタの種類（優先度：高）
#message{
  background-color: yellow;
}
```
この場合って「セレクタの種類」「セレクタの詳細度」「コードが記載される箇所」のファクター同士の優先度が分からないと答えが出せませんよね…😓
<b>なので、それぞれ検証してみましょう！

# 5.検証
<b>検証内容：どのファクターの優先度が高いのか確認する。</b>
検証結果を以下の表で整理します。

||セレクタの種類|セレクタの詳細度|コードが記載される箇所|
|-|-|-|-|
|セレクタの種類|-|||
|セレクタの詳細度||-||
|コードが記載される箇所|||-|

## 5.1 【検証1】セレクタの種類×セレクタの詳細度
検証コード
```scss:検証1
//スタイル9
//セレクタの種類（優先度：低）
//セレクタの詳細度（優先度：高）
.test1{
  .test2{
    .message{
      background-color: red;
    }
  }
}

//スタイル10
//セレクタの種類（優先度：高）
//セレクタの詳細度（優先度：低）
#message{
  background-color: yellow;
}
```

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/04784eec-f1fb-1c0c-0710-d8590d171ba8.png)
<b>結果：「セレクタの種類」の方が「セレクタ詳細度」より優先度が高い
||セレクタの種類|セレクタの詳細度|コードが記載される箇所|
|-|-|-|-|
|セレクタの種類|-|⭕||
|セレクタの詳細度|✖|-||
|コードが記載される箇所|||-|


## 5.2 【検証2】セレクタの種類×コードが記載される箇所
検証コード
```scss:検証2
//スタイル11
//セレクタの種類（優先度：高）
//コードが記載される箇所（優先度：低）
#message{
  background-color: blue;
}

//スタイル12
//セレクタの種類（優先度：低）
//コードが記載される箇所（優先度：高）
.message{
  background-color: green;
}
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/325cbabc-03e6-107e-a3e5-91a1b4d67edd.png)
<b>結果：「セレクタの種類」の方が「コードが記載される箇所」よりも優先度が高い
||セレクタの種類|セレクタの詳細度|コードが記載される箇所|
|-|-|-|-|
|セレクタの種類|-|⭕|⭕|
|セレクタの詳細度|✖|-||
|コードが記載される箇所|✖||-|

## 5.3 【検証3】セレクタの詳細度×コードが記載される箇所
検証コード
```scss:検証3
//スタイル12
//セレクタの詳細度（優先度：高）
//コードが記載される箇所（優先度：低）
.test2{
  .message{
    background-color: pink;
  }
}

//スタイル13
//セレクタの詳細度（優先度：低）
//コードが記載される箇所（優先度：高）
.message{
  background-color: purple;
}
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/e907073e-9f66-cca9-39e4-ad189a69f5e9.png)
<b>結果：「セレクタの詳細度」の方が「コードが記載される箇所」よりも優先度が高い
||セレクタの種類|セレクタの詳細度|コードが記載される箇所|
|-|-|-|-|
|セレクタの種類|-|⭕|⭕|
|セレクタの詳細度|✖|-|⭕|
|コードが記載される箇所|✖|✖|-|

:::note
結論:　ファクター同士の優先度は「<b>セレクタの種類>セレクタの詳細度>コードが記載される箇所</b>」
:::


# 6.優先度についてまだ把握不足な箇所がある🙄
以下のコードはどちらが優先されると思いますか？
```scss:example5
//スタイル14
//セレクタの種類（優先度：低）
//セレクタの詳細度（優先度：高）
//コードが記載される箇所（優先度：低）
.test2{
  p{
    background-color: purple;
  }
}

//スタイル15
//セレクタの種類（優先度：高）
//セレクタの詳細度（優先度：低）
//コードが記載される箇所（優先度：高）
.message{
  background-color: pink;
}
```
答えは…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/f6d1dc03-e0b6-2c57-3c25-e176188db86b.png)
`スタイル14`が優先されるんです！
 ~~これが私の中でまだ消化不良を起こしております。~~

~~親要素のセレクタの種類が優先度に影響を及ぼしている？🤔~~
~~ご存じの方がいたら教えてください🙏~~

@angeartさんにすごく納得のいく回答をして頂きました！！😁(この記事のコメント欄参照)
セレクタ―によって重みが違うみたいですね。
idセレクタ―にはクラスセレクタ―がいくら集まっても勝てないみたいな
詳細は以下をご覧ください。
https://developer.mozilla.org/ja/docs/Web/CSS/Specificity

# 7.`scss`についてまだ理解不足だが「プロパティが適用されない不具合😭」を起こさないために
`scss`を完全に理解できればよかったのですが、私の分析力ではこれが限界でした。ではどのようにして「`scss`が適用できていない」不具合を防げばよいでしょう？

私はコードを追加する時に<b>【めんどくさがらずに既存scssコード構造の中に追加すること❗❗】</b>を提案します。😄（それが普通では？🤔）

コードを追加する際、私は既存コードを読むのが面倒なので一番下に追加コードを書いていました。
```scss
//既存のコード
.test1{
  p{
    background-color: purple;
  }
}

//追加したコード
.message{
  background-color: pink;
}
```
このような書き方をすると、優先度の沼にハマってしまいます…
これを今日からやめます！！
明日からは、後付けせずに既存コードの構造の中にちゃんと書くようにします！
```scss
//既存のコード
.test1{
  p{
    background-color: purple;
  }
  //追加したコード
  .message{
    background-color: pink;
  }
}
```

こうすればリーダブルになりますし、親要素の違いによって優先度が混乱することもありません！（親要素を共通にしたため、基本ルールだけに従って優先度を把握できる。🙌）


# 6. さいごに
`scss`ってプロぐらいミング言語じゃないから簡単でしょ（笑）
とか思ってました。😭
深堀していくとまだまだ分からないことがたくさんありました。
今後は`scss`と<b>"ちゃんと"</b>向き合いたいと思います！

`scss`について、分かったことがあれば、また記事にしたいと思っておりますのでよろしくお願いします！😀