【CSSセレクター完全版】覚えるべきCSSセレクターまとめ

#・初めに
この記事は以下の方を対象としています。また、記事修正のコメントやLGTMなどモチベーションにつながるのでよろしければお願いします‼

+ 初学者の方
+ フロントエンドエンジニア志望の方
+ セレクターについて学習したい方

#・導入
閲覧ありがとうございます。この記事は、初学者がフロントエンド目指してロードマップに沿ってアウトプットしていく記事になります。
こちらの記事はPart7です。最初からご覧になりたいかたは、以下よりどうぞ。

>[Roadmap](https://github.com/kamranahmedse/developer-roadmap/blob/master/img/frontend.png?raw=true)

#・記事一覧
[part1: Internet【HTTP,Browsers】](https://qiita.com/n4suka7/items/ac3c16b3e30ec59fff0d)
[part2: Internet【DNS,Domain,Hosting】](https://qiita.com/n4suka7/items/decb31c452cd8efbf4cb)
[part3: HTML 【basics】](https://qiita.com/n4suka7/items/75be9cd6e5d68d99ccb3)
[part4: HTML 【Form validation】](https://qiita.com/n4suka7/items/74becbf95fdab29b8a1c)
[part5: HTML 【20 best practices】](https://qiita.com/n4suka7/items/2d04f2bff22a91d6a925)
[part6: CSS  【basics】](https://qiita.com/n4suka7/items/9f4a42fe5b3beb75b189)

#・Part7　CSSセレクター
ウェブページ上のHTML要素にスタイルを設定するためには、**セレクター**が使用されます。セレクターにはさまざまな種類があり、より詳細にスタイルを設定する要素を選択することができます。

##要素・クラス・IDによるセレクター
###タイプセレクター
**タイプセレクター**はHTMLの要素を参照し、参照された要素に対して適用させることができます。言葉ではわかりずらいので、以下に簡単な例を設けています。早速見ていきましょう。

>以下のコードでは、外部スタイルシートでhtmlファイルにCSSファイルが読み込まれており、その他のhtmlコードも記述されている前提で話を進めていきます。(すべて書くとコードが長くなってしまうため)


```html:index.html
<main>
  <h1>スポーツ速報</h1>
　　　<h2>プロ野球速報</h2>
　　　　　<p>ロッテが33－4で勝ちました。</p>
　　　<h2>メジャー速報</h2>
　　　　　<p>大谷翔平がホームランを打ちました。</p>
</main>
```

```css:style.css
h1 {
  color: red;
}
h2 {
  color: blue;
}
```

タイプセレクターの理解は簡単で、セレクターで指定された要素にCSSが当てあられます。例を具体的にみると`<h1>`は赤文字に、`<h2>`は青文字になります。しかし、`<h2>`は2つあるので両方青文字になることに注意が必要です。
また、`<body>`を指定するとページ上では全画面にCSSが適用されます。背景の色を変える際などに使用することがあるので覚えておきましょう。

###クラスセレクター
**クラスセレクター**は、そのクラスが適用されている要素すべてを選択します。似ていますが、タイプセレクターと違って `.` (ドット)から始めている点に注意が必要です。また、同名のクラスが複数ある場合はそのクラスすべてにCSSが適用されますが、同名のクラスの中で特定の要素を指定することも可能です。下の例でみていくと、`mlb`クラス2つのうちの`<span>`のみに適用したい場合、`style.css_2`に書いてあるように`要素.セレクター`で選択することができます。

```html:index.html
<main>
  <h1 class="sports">スポーツ速報</h1>
　　　<h2 class="npb">プロ野球速報</h2>
　　　　　<p>ロッテが33－4で勝ちました。</p>
　　　<h2 class="mlb">メジャー速報</h2>
　　　　　<p>大谷翔平がホームランを打ちました。</p>
　　　　　<p>ダルビッシュ有がホームラン<span class="mlb">!!!!!</span>を打ちました。</p>
</main>
```

```css:style.css
.npb {
  color: red;
}
.mlb {
  color: blue;
}
```

```css:style.css_2
.npb {
  color: red;
}
span.mlb {
  color: blue;
}
```

`.npb`で指定されている部分が赤文字になり、`.mlb`で指定されている部分が青文字になります。
style.cssでは`<h2>,<span>`どちらも青文字ですが、style.css_2では前述の通り、`<span>`のみに青色が適用されます。

###idセレクター
idセレクターはそのidが適用されている要素のすべてを選択します。クラスセレクターと違って、`#`から始めます。また、idはそのドキュメント内で一意(1つのみ)でなければならないため、クラスのような複数選択はできません。

>**・注意　idセレクターは詳細度が高く、スタイルの上書きなどを行いたい場合などに非常にややこしくなってしまうため、基本的にはクラスセレクターを使用することが推奨されています。**

```html:index.html
<main>
  <h1 id="sports">スポーツ速報</h1>
　　　<h2 id="npb">プロ野球速報</h2>
　　　　　<p>ロッテが33－4で勝ちました。</p>
　　　<h2 id="mlb">メジャー速報</h2>
　　　　　<p>大谷翔平がホームランを打ちました。</p>
</main>
```

```css:style.css
#npb {
  color: red;
}
#mlb {
  color: blue;
}
```
`#npb`で指定されたところは赤く、`#mlb`で指定されたところは青い文字になります。

###ユニバーサルセレクター
ユニバーサルセレクターは、アスタリスク(*)で表され、ドキュメントのすべてまたは親要素に含まれるすべての要素を選択します。

```html:index.html
<main>
  <h1>スポーツ速報</h1>
　　　<h2>プロ野球速報</h2>
　　　　　<p>ロッテが33－4で勝ちました。</p>
　　　<h2>メジャー速報</h2>
　　　　　<p>大谷翔平がホームランを打ちました。</p>
</main>
```

```css:style.css
main * {
  color: red;
}
```

main に * がついているため、`<main>`(親要素)とその子要素はすべて赤文字になります。例でいうと、`<h1>,<h2>,<p>`のすべての文字が赤くなります。

##属性によるセレクター
これまでと同じように、HTML要素の属性に対しても**属性セレクター**を使用して、属性の とある要素 を選択することができます。

###値のセレクター
これによって、さまざまな属性の値に対して選択することができるようになり、`要素[属性]`というような形を用いることによって使用することができます。一例に過ぎませんが、以下を見ていきましょう。

```html:index.html
<main>
  <h1>スポーツ速報</h1>
　　　<a href="npb.jp">プロ野球速報</a>
     <a href="mlb.jp">メジャー速報</a>
</main>
```

```css:style.css
a[href] {
  color: green;
}
```

この場合、`<a>`のhref属性を持つすべてに`color:green;`が適用されるので、プロ野球速報、メジャー速報どちらのリンクも緑文字になります。

###部分文字列一致セレクター
部分文字列一致セレクターを使うことで、属性の中の文字列をより詳しく選択することができます。見たほうがわかりやすいので、以下の例でみていきましょう。

```html:index.html
<main>
  <h1>スポーツ一覧</h1>
    <ul>
　　　 <li class="a">プロ野球速報</li>
      <li class="ab">メジャー速報</li>
　　　 <li class="cba">ゴルフ速報</li>
    </ul>
</main>
```

```css:style.css
例1
li[class^="a"] {
  color: green;
}
例2
li[class$="a"] {
  color: red;
}
例3
li[class*="a"] {
  color: blue;
}
```

+ 例1を適用した場合　
`li[class^="a"]`といったように`^`を使用することで、**a で始まるclass属性の値の中の部分文字列(要するに"a")を選択することができる**ので、1,2番目のリストが緑文字になります。

+ 例2を適用した場合　
`li[class$="a"]`といったように`$`を使用することで、**a で終わるclass属性の値の中の部分文字列を選択することができる**ので、1,3番目のリストが赤文字になります。

+ 例3を適用した場合
`li[class*="a"]`といったように`*`を使用することで、**a がどこかに含まれるclass属性の値の中の部分文字列を選択することができる**ので、すべてのリストが青文字になります。

##疑似クラスによるセレクター
**疑似クラス**とは、特定の状態にある要素を選択するセレクターで、`要素:疑似クラス名`で表されます。疑似クラスには多くの種類がありますが、ここではいくつか紹介していきたいと思います。

###・`:first-child`,`:first-of-type`
これらは、要素のグループの中で1番目の要素を選択するときに使用します。しかし、2つには微妙な違いがあります。それは、`:first-child`は親要素の1番目を選択し、`:first-of-type`は指定されたタグの中で1番目というように数えていく点です。難しいので、例を見ていきましょう。

```html
<article>
  <h1>大谷翔平の記録</h1>
  <p>打っては40本ホームラン</p>
  <p>投げては15勝</p>
  <p>走っては60盗塁</p>
</article>
```

```css
article p:first-child {
  color: red;
}
```
```css
article p:first-of-type {
  color: blue;
}
```
`:first-child、:first-of-type`どちらにおいても、articleの`<p>`の1番目の子要素を選択するので、1番目の`<p>`(打っては40本ホームラン)に各色が当てられそうですが**それは間違い**です。なぜなら、articleの最初の子要素は`<h1>`であり、`<p>`ではありません。そのため、`:first-child`を使用した場合「1番目は`<h1>`で`<p>`じゃないからCSS当てられないや～」といった具合にうまく機能しません。逆に言えば、`:first-of-type`を使用した場合、「`<p>`のなかで1番目は`打っては40本ホームラン`だからここの文字を青にするか」といった具合にうまくCSSをあてることができます。

###・`:last-child`,`:nth-child`,`:last-of-type`,`:nth-of-type`
これらはn番目や最後を指定する方法で、ロジックは`first`とほぼ同じです。指定したい番号nを自由に変化させて使いましょう。`last~`はもちろん、最後の要素を選択するために使用します。

###・`:hover`
`:hover`は、ユーザーアクションの疑似クラスや動的疑似クラスと呼ばれ、ユーザーが要素を操作したときに、要素にクラスが追加されたかのように動作することを指します。例をみていきましょう。

```css
p:hover {
  background-color: red;
}
```

このようにすることで、`<p>`に対してポインター(マウスカーソル)がhoverされたときに、このCSSが適用されます。逆を言えば、hoverされなければ適用されないので、見た目上ではCSSは適用されていません。

##疑似要素によるセレクター
疑似要素は、既存の要素にクラスを適用するのではなく、まったく新しいHTML要素をマークアップに追加したかのように動作し、`要素::疑似要素名`で選択することができます。ここでもいくつかみていきます。

###`::after`,`::before`
文字通り、選択した要素の後ろか前に適用させることができます。例をみていきましょう。

```html
<article>
  <h1>大谷翔平の記録</h1>
  <p>打っては40本ホームラン</p>
  <p>投げては15勝</p>
  <p>走っては60盗塁</p>
</article>
```

```css
h1::after {
  content: "!!!!!"
}
```

このようにすることで、`<h1>`の後(具体的にみれば、`大谷翔平の記録`のあと)に"!!!!!"がcontentプロパティによって追加され、`大谷翔平の記録!!!!!`となります。
しかし、これらの多くは文字列でなく、アイコンの挿入などに使用されることが多いです。

###`::first-line`,`::first-letter`
`::first-line`は、要素の最初の行を選択することができます。また、`::first-letter`を使用することで最初の文字を選択することができます。それぞれ使いどころは限定させるかと思いますが、覚えておきましょう。

>ほかの疑似クラスと疑似要素についてみたい方は[こちら](https://developer.mozilla.org/ja/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements)

##結合子
結合子は、セレクターとドキュメント内のコンテンツの場所や関係などを結びつける役割を持っているものを指します。具体的にみていきましょう。

###子孫結合子
子孫結合子は、今までなんとなく出てきていた`article h1 {color: red;}`のように、スペース(" ")を用いて、セレクターを結合する役割を持っています。子孫要素を増やして、より選択範囲を限定することが可能ですが、コードの可読性に影響が出るため、できるだけ簡単に記述することがいいとされています。

```html
<main>
  <h1>大リーグ速報</h1>
  <article>
    <h1>大谷翔平の記録</h1>
    <p>打っては40本ホームラン</p>
    <p>投げては15勝</p>
    <p>走っては60盗塁</p>
  </article>
</main>
```

```css
main article h1  {
  color: red;
}
```

とすると、`<main>`の中の`<article>`のなかの`<h1>`が選択されるため、同じ`<h1>`でも`大リーグ速報`ではなく、`大谷翔平の記録`が赤文字になるというのはもう簡単に理解できると思います。また、各要素の間にあるスペースが子孫結合子を表しています。

###子結合子
子結合子は、セレクターの直接の子である要素に対して選択する場合に使用し、`>`で表されます。言葉では難しいので例をみていきましょう。

```html
<main>
  <h1>大リーグ速報</h1>
  <article>
    <h1>大谷翔平の記録</h1>
    <p>打っては40本ホームラン</p>
    <p>投げては15勝</p>
    <p>走っては60盗塁</p>
  </article>
</main>
```

```css
main > h1 {
  color: red; 
}
```

`<h1>大リーグ速報</h1>`を選択したいとき、`main h1 {}`で選択できそうですが、よく見ると`<article>`の中にも`<h1>`があるため、これだとどちらも選択されてしまいます。そこで、`main > h1 {}`と記述することで、`<main>`の直接子要素である`<h1>大リーグ速報</h1>`のみを選択することができます。リストのスタイリングなどで使用されることが多いので、しっかりと覚えておきましょう。

###隣接兄弟結合子
隣接兄弟結合子は、選択した要素から2つ目以降の要素を選択し、`+`で表されます。例をみていきましょう。

```html
<article>
    <h1>大谷翔平の記録</h1>
    <p>打っては40本ホームラン</p>
    <p>投げては15勝</p>
    <p>走っては60盗塁</p>
</article>
```

```css
article p + p {
  color: green;
}
```

このようにすることで、3つある`<p>`のうち最初を除いた残り2つの`<p>`を緑にすることができます。2つ目の要素から何かCSSをあてたいときに便利ですので、覚えておきましょう。

###一般兄弟結合子
要素が直接隣接していなくても、その要素の兄弟を選択したい場合は、一般的兄弟結合子を使用し、`~`で表します。例をみていきましょう。

```html
<article>
    <h1>大谷翔平の記録</h1>
    <p>打っては40本ホームラン</p>
    <div>マジすごすぎ</div>
    <p>走っては60盗塁</p>
</article>
```

```css
article h1 ~ p {
  color: red;
}
```

この場合、`<article>`の`<h1>`以降にあるすべての`<p>`を選択することができます。そのため、結果としては、2，4番目にある`<p>`が赤になります。また、一般兄弟結合子は`<h1>`より後ろの要素選択されるため、例えば`<h1>`を3番目に移動させた場合は、4番目の`<p>`のみ選択されることに気を付けましょう。

#次回予告
今回はセレクターについてまとめてきました。このほかにも多くのセレクターがありますが、使うときに調べて覚えていきましょう。次回はCSSについてもっと詳しく見ていきたいと思います。

#参考文献
[MDN Web Docs](https://developer.mozilla.org/ja/docs/Learn/CSS/Building_blocks/Selectors)