nth-childのof構文でより高度な指定ができるようになったのでnth-of-typeとの違いを改めて整理してみる

## これはなに？

CSSプロパティの `nth-chlid()`と `:nth-last-child()` に of構文でより詳細なフィルタリングができる様になりました。
この記事では、その挙動と `nth-child()` と `nth-of-type()` の違いを理解したいと思います。

## `nth-child()`と`nth-of-type()`の挙動

- `nth-child()` は兄弟要素のグループの中での位置に基づいて選択します
- `nth-of-type()` は兄弟要素のグループの中で指定された型 (タグ名) の要素の位置に基づいて選択します

例えば、`dl`,`dt`, `dd`で記述した下記のグリッドがあります。
どちらも3つめの要素の背景を変更するCSSを記述しました。

- `dd:nth-child(3)` では、`dt` を含めた3つめの背景をピンクに変更しています
- `dd:nth-of-type(3)` では、`dd`だけの３つめの背景を緑に変更しています

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ExrqyRm" data-user="gilly135" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/gilly135/pen/ExrqyRm">
  nth-child/nth-of-type</a> by gilly135 (<a href="https://codepen.io/gilly135">@gilly135</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

このように、`nth-child()`と`nth-of-type()`では挙動の違いがあることは広く知られているのではないでしょうか。

## ｎ番目の指定

`nth-child()`と`nth-of-type()`ともに、n番目の指定方法は同じです。

### 特定の番号の指定（n番目）

例えば３番めの要素の指定は下記のように書きます。

```css
nth-child(3) or nth-child(0n+3)
nth-of-type(3) or nth-of-type(0n+3)
```

### 奇数の指定（2n+1）

奇数の要素を指定したいときは、下記のように書きます。

```css
nth-child(2n+1) or nth-child(odd)
nth-of-type(2n+1) or nth-of-type(odd)
```

### 偶数の指定(2n)

偶数の要素を指定したいときは、下記のように書きます。

```css
nth-child(2n) or nth-child(even)
nth-of-type(2n) or nth-of-type(even)
```

### 倍数（Xn）

例えば3の倍数を指定したいときは下記のように書きます。

```css
nth-child(3n)
nth-of-type(3n)
```

### Y番目以降(n+Y)

例えば5番目以降の要素を指定したいときは下記のように書きます。

```css
nth-child(n+5)
nth-of-type(n+5)
```

### Y番目まで(-n+Y)

例えば5番目までの要素を指定したいときは下記のように書きます。

```css
nth-child(-n+5)
nth-of-type(-n+5)
```

### 倍数とY番目の組み合わせ(Xn+Y)

例えば、2番目から3の倍数ごとに指定したいときは下記のように書きます。

```css
nth-child(3n+2)
nth-of-type(3n+2)
```

### n番目以外(:not)

例えば、2番目以外に指定したいときは `:not` という否定疑似クラスを使って、下記のように書きます。

```css
dd:not(:nth-child(2))　{}
dd:not(:nth-of-type(2))　{}
```

### A番目からB番目まで

複数組み合わせることもできます。
例えば、3番目から5番目を指定したいときは下記のように書きます。

```css
dd:nth-child(n+3):nth-child(-n+5)
dd:nth-of-type(n+3):nth-of-type(-n+5)
```

### その他

他にも特定の指定方法ができるCSSのプロパティがあります。

指定|`nth-child`系|`nth-of-type`系
---|---|---
最初|:first-child|:first-of-type
最後|:last-child|:last-of-type
後ろからn番目|:nth-last-child(n)|:nth-last-of-type(n)
１つだけ|:only-child|:only-of-type

## `nth-child()`のof構文によるフィルタリング

冒頭でも述べましたが、CSSプロパティの `nth-chlid()`と `:nth-last-child()` に of構文でより詳細なフィルタリングができる様になりました。
上記の様にn番目の構文と組み合わせて特定のクラスのフィルタリングができます。

例えば、`.pickup` というclassがついた要素の3番目の要素にオレンジの枠線をつけるときは下記のように書きます。

```css
dd:nth-child(3 of .pickup) {
  border: 2px solid #fb8c00;
}
```

### `nth-of-type()` と `nth-child()`のof構文によるフィルタリングの違い


`nth-of-type()`は特定の型（タグ名）の要素の要素の位置に基づいて選択します。
仮に`.pickup:nth-of-type(1)` で１番目の `.pickup` に青色の枠線をつけたかった場合、`dl`,`dt`,`dd`で記述したサンプルの`dt`,`dd`に `.pickup`をつけるとどうなるでしょうか。


```css
.pickup:nth-of-type(1) {
  border: 2px solid #1e88e5;
}
```

出力結果は下記のコードサンプルをご覧いただければと思いますが、`<dt class="pickup">Dog</dt>`にも、`<dd class="pickup">Pomeranian</dd>`にも青い枠線が付きました。

複数のタグにも同じようなclass名がついた場合、 `nth-child()` のof構文でのフィルタリングがわかりやすくなります。
場合によって使い分けて行けると良いと思います。

### コードサンプル

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZEwgOvW" data-user="gilly135" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/gilly135/pen/ZEwgOvW">
  Untitled</a> by gilly135 (<a href="https://codepen.io/gilly135">@gilly135</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## サポートブラウザ

MDNによるとof構文はすべてのブラウザで利用できるようです。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215239/d29bc8d1-0bf6-6e7e-453c-da90239b6410.png)


この記事が誰かのお役に立てると幸いです。

## 参考

- [S 構文を使用して :nth-child() の選択をより詳細に制御  |  CSS and UI  |  Chrome for Developers](https://developer.chrome.com/docs/css-ui/css-nth-child-of-s?hl=ja)
- [:nth-child() - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/:nth-child)
- [:nth-of-type() - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/:nth-of-type)
- [要素の指定にもう迷わない？:nth-child()のofフィルターを使ったラクラク要素指定法 | フロントエンドBlog | ミツエーリンクス](https://www.mitsue.co.jp/knowledge/blog/frontend/202008/27_1110.html)