CSS入れ子を道草食べすぎながら理解する

# はじめに
道草って美味しいですよね。世の中には多種多様な道草があります。シロツメクサとかいい感じな味がして美味しいですし、たんぽぽはなんかしらんが刺身の上に乗っていますし、よもぎは普通に食えます。ながすなりです。

そんな戯言はさておき、CSS入れ子ってなんぞ？ってなりました。よくわかんなかったので、調べました。そうしたらさらにわかんない概念がたされましたので、それを調べたら、さらによくわかんなくてさらに調べて、わかんなくて...世の中こんなんばっかです。

**...神は死んだ** 

天を仰いでそう言いたくなりましたが、頑張って一つ一つ理解しました。私だけでその理解を占有するのも勿体無いと思ったので、無知な皆様にも共有することにしました。...えっ？もう知ってるって？...次行きましょう。

ちなみに筆者はゴリゴリのサーバーサイドなんで、html,cssは齧ったくらいしかないです。適度な塩加減で微妙に美味しいのだけは知ってます。なので詰まるところが多すぎると思うのですが、ニコニコしながら見るのが多分エンタメ的に正解です。

# CSS入れ子ってなんぞ？（1回目）
CSS入れ子ってなんぞ？そう思ったわけです。ググるとこんな素晴らしいページが。

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


>CSS 入れ子 (CSS nesting) モジュールは、セレクターを入れ子にする構文を定義し、親ルールのセレクターに対して子ルールのセレクターを相対的に指定することで、あるスタイルルールを別のスタイルルールの中に入れ子にする機能を提供します。

↑こんな素晴らしい文言が書いてあるわけなんですが、ちんぷんかんぷんなわけです。一つ一つ解いていきましょう。千里の道も一歩から、一人の人間にとっては小さな一歩だが、人類にとっては大きな一歩なのであります。

- モジュールってなんぞ？
- セレクターってなんぞ？
- 親ルール,子ルールってなんぞ？
- スタイルルールってなんぞ？

まぁ大体こんな感じですかね？入れ子に関しては一般教養だと思いたいですし、思ってます。ともあれこいつらがわからんと、CSS入れ子がわからんわけです。一個ずつ調べましょう。

# モジュールってなんぞ？
若干モジュールも一般教養の匂いがぷんぷんしますが、一般教養のない私がわからなかったので調べてます。明確な定義が見つからなかったのですが、以下のような使われ方をしています。つまりはCSS上での意味ごとのまとまりくらいの感じなんですかね？いい定義は思いつきませんが、何となくふわっとはわかった気がします。
> CSS アニメーション (CSS Animations) は CSS のモジュールの一つ

> CSS 色 (CSS Color) は CSS のモジュールで、色、色の種類、色の混合、透過性、そしてどのようにこれらの色や効果を HTML コンテンツに適用するかを扱います。

なんかふわっとしていて嫌だったので、gptに聞きました。
>CSSにおける「モジュール」とは、特定の機能や目的を持ったスタイルや規則の集合を指します。

大体あってましたね。gptが嘘をついていなければですが。

# セレクターってなんぞ？
何となくは知ってるんですけど知らない言葉ランキング堂々の3位ですね。ちなみに一位は資本主義です。

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

> CSS セレクターモジュールは、要素を選択するパターンを定義し、一連の CSS ルールをその詳細度とともに適用します。 CSS セレクターモジュールには、 60 以上のセレクターと 5 つの結合子が用意されています。他のモジュールは、さらに擬似クラスセレクターと擬似要素が提供されています。

またよくわからん言葉がいくつか出てきました。モジュールは何となく理解したので、多分大丈夫です。セレクタもモジュールなんすね。
- 要素ってなんぞ？
- パターンは聞いたことありそう？
- CSSルールはしらん？
- 詳細度とは？
- 結合子？美味しいの？
- 擬似セレクタ？擬似要素？

CSS入れ子よりもよくわからん話になってまいりました。正直この時点で辞めようかなと思いましたが、わからないままにするとイライラするので、調べることにしました。道草を私と一緒に食べましょう。青臭くて美味いやつもたまにはありますよ？

## 要素ってなんぞ？
似たようなページに答えに漸近できそうな記述がありました。

https://developer.mozilla.org/ja/docs/Learn/CSS/Building_blocks/Selectors
> CSSでは、セレクター (selector) を使って装飾したい HTML 要素を選択します。

じゃあ要素じゃなくてHTML要素って書いてくれねぇかなぁ！ってキレそうになったのは内緒にしてください。html,cssを触る上で要素って言ったら、暗黙的にHTML要素なんでしょうね。知らん私が悪いか...。と思いましたが、html要素だけでなく、classとかも指定するので、要素が正しいのでしょう。となると`要素を選択するパターン`の意味が何となくわかりました。↓のspanみたいなやつのことですね。つってもパターンっていう日本語微妙にしっくりこないのでもうちょい調べることとします。
``` css
span {
    color: red;
}
```

## パターンとは
おそらくここで使われているパターンは一般名詞をちょっと特殊に使っている感じで、普通に調べても多分出てこないので、chatGPTちゃんに聞きました。パターン ≒ 一連の規則や構文と考えればよさそうですね。

> CSSセレクタの文脈で「パターン」とは、特定の要素を選択するための一連の規則や構文を指します。

## CSSルールはしらん？
何となく想像はつくのですが、まぁしっかり調べてみましょう。道草意外と美味しいですからね。簡単に調べてもドンピシャな回答が得られなかったので、chatGPTで調べました。CSSルールとかいう専門用語っぽいものを使うならば解説くらい置いておけやと思うのはきっと傲慢なのでしょうね...。

> CSSルールは、ウェブページのスタイルを定義するための基本的な構造です。CSSルールは主にセレクタ（どの要素にスタイルを適用するか）と宣言ブロック（適用するスタイル）で構成されています。

非常にわかりやすいですね。CSSの書き方がCSSルールと呼ばれるようです。要するに↓のような書き方をCSSルールと呼ぶわけです。`span`がセレクタで、`{...}`内が宣言ブロックのようですね。

``` css
span {
    color: red;
}
```

## 詳細度とは？
正直こいつが一番デカそうだなと思っていました。こいつだけダントツで文字から得られる情報が少ないので、手強そうです。

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

> 詳細度 (Specificity) は、ある要素に最も関連性の高い CSS 宣言を決定するためにブラウザーが使用するアルゴリズムで、これによって、その要素に使用するプロパティ値が決定されます。詳細度のアルゴリズムは、CSS セレクターの重みを計算し、競合する CSS 宣言の中からどのルールを要素に適用するかを決定します。

道草増加確定演出です。CSS宣言はCSSルールの内容から何となく想像がつきます。おそらくはCSSルールの構成要素である、中括弧で囲まれた宣言ブロックのことでしょう。でも違う可能性もあるので、調べておきましょう。

- What is CSS宣言
- 重みとは何ぞ？

### What is CSS宣言

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

> プロパティと値の組は宣言と呼ばれ...

`color: red` これを宣言と呼ぶようです。コロンより左側をプロパティ、右側を値と呼称することもわかりました。そして宣言をまとめたものを宣言ブロックというようですね。こうすると`その要素に使用するプロパティ値が決定されます`という文言が微妙によくわからんですね。プロパティと値が決まるということなのでしょうか？まぁそういうことでしょう。

### 重みとは何ぞ？
これは詳細度のページの下の方に書いてありましたね。詳しくはそちらを読んでください。やってることはシンプルですが、わかりやすく説明するのは難しいので、任せます。簡単に要点だけをいうと、CSSセレクタのid,class,type,無し,の四つの重みはidが一番強く、無しが一番弱いって感じです。ざっくりしすぎですかね？

### 詳細度が何となくわかった
詳細度という日本語は正しいんだけど、正確なわけではなさそうです。一言で言えと言われると難しいですが、対象としたいその要素に対してどれだけ詳細に記述しているかという指標なわけですね。以下のようなcssがあった場合、`<span id=ex>`というhtmlがあったときにそのhtmlをより詳細に記述しているのは下なので、下の`color: blue`が適用されるというロジックなのでしょう。詳細に記述しているという日本語も説明できていなくてもどかしいのですが、何となく詳細度がわかりました。

``` css
    span {
        color: red;
    }

    span#ex {
        color: blue;
    }
```

## 結合子とは？
もう結構疲れてきたので、辞めたいところですがもうちょい頑張ります。｜ここから休憩して一週間後に書いているので結構元気です。調べていきましょう。

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_selectors/Selectors_and_combinators

> CSS セレクターは、選択した要素に一連の CSS ルールを適用するために、選択する要素のパターンを定義するために使用します。結合子は、セレクター間の関係を定義します。様々なセレクターと結合子を使用することで、入力する要素の型、属性、状態、他の要素との関係に基づいて、必要な要素を正確に選択し、スタイル設定することができます。

ここにドンピシャで書いてありました。ドンピシャに書いてあるからと言って、理解できるとは限らないということがよくわかりました。一つ一つ頑張って理解していきましょう。

とりあえず`結合子は、セレクター間の関係を定義します。`という文章が結論です。セレクター間の関係ってなんぞ？ってなるわけですね。私も分かりません。結合子の例を見てみましょう。

``` css
h2 + p ~ p {
  font-style: italic;
}
```

`h2 + p ~ p`のあたりが確かにセレクター間の関係を定義しているみたいですね。`+`が`次兄弟結合子`というらしく、詳しい説明はドキュメントに譲りますが、`h2 + p`とかだと`h2`の次の単一の`p`を修飾してくれるっぽいです。そんな風に複雑にセレクタを指定できるので、複雑セレクタといわれるらしいです。

# 擬似セレクタ？擬似要素？

https://developer.mozilla.org/ja/docs/Web/CSS/Pseudo-classes

これは分かりやすいですね。`:hover`などの選択された要素の特定の状態を指定するものらしいです。

# CSS入れ子ってなんぞ？(2回目)

必要な知識は仕入れました！頑張って理解していきましょう。もう一度定義文を置いておきます。

> CSS 入れ子 (CSS nesting) モジュールは、セレクターを入れ子にする構文を定義し、親ルールのセレクターに対して子ルールのセレクターを相対的に指定することで、あるスタイルルールを別のスタイルルールの中に入れ子にする機能を提供します。

読める...読めるぞ...!失礼。ムスカになってしまいました。ただ意味は分かったけれど、どういう良さがあるのとか、どういうときに使うの？というのはぱっと出てこないので、例を見てみましょう。

``` css
.parent-rule {
  /* スタイルプロパティ */
  &:hover {
    /* スタイルプロパティ */
  }
}
```

こういう感じで書くようで、`&`がCSS入れ子セレクタのようですね。この時の意図としては`parent-rule`が`:hover`の時にhover内のcss宣言を適用したいという意図です。なぜCSS入れ子を使う必要が有るのでしょう。

```
.parent-rule {
  /* 親ルールスタイルプロパティ */
  :hover {
    /* 子ルールスタイルプロパティ */
  }
}

```
↑これでいいじゃんと思いますよね。私も思いました。ですがこれは↓と同等らしいです。

```

.parent-rule {
  /* 親ルールスタイルプロパティ */
}

.parent-rule *:hover {
  /* 子ルールスタイルプロパティ */
}


```

これだと`parent-rule`の子孫全部の`:hover`状態に指定したcss宣言が適用されるようです。これは意図した動作ではありません。

結局よくわかんなかったので、書いてみることにしました。

### CSS入れ子を使ったバージョン
![hover_before.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3461855/0684930e-1f46-ace8-f6f8-9527c65be08b.gif)

### 使わなかったバージョン
![hover_after.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3461855/2e39d358-23c5-3c83-2d1f-d0432621aaaa.gif)


```html
<!-- <!DOCTYPE html> -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Parent Rule Hover Test</title>
    <style>
        .parent-rule {
            background-color: lightblue;
            padding: 20px;
            text-align: center;
            /* 親ルールスタイルプロパティ */
            &:hover{
                background-color: lightcoral;
            /* 子ルールスタイルプロパティ */
            }
        }
    </style>
</head>
<body>
    <div class="parent-rule">
        Hover over me to see the effect!
    </div>
</body>
</html>
```

こんなコードで`:hover`の前の&をつけたり外したりでしました。つまりcss入れ子でやりたいことって、↓こういうことなんです。でもこれだと見づらいよね？可読性悪くね？ってことでCSS入れ子があるのかなと思っています。CSS入れ子を使うことで下のように親ルールを何回も書かなくてよくなり、構造化されるので見やすくなるなぁと思っています。
```html
.parent-rule {
  /* 親ルールスタイルプロパティ */
}

.parent-rule:hover {
  /* 子ルールスタイルプロパティ */
}
```



# まとめ
道草を食べ過ぎながら、CSS入れ子を理解したつもりです。まぁDOMノードはなんじゃらほいとか、じゃあ実際こういう場合は？みたいな具体的なことにはまだこたえられる気はしていませんが、なんとなーくCSS入れ子ってこんなんだよねぇーってのは語れるようになった気がしています。

これを見て、へぇそーなんだぁってなってくれれば幸いです。そいつはとりあえずいいねを押しておいてください。