「n番目の要素」という指定ができる”:nth-child(n)”系の疑似要素ですが、注意しなければいけない点と、案外知られていない便利なバリエーションがあるので、まとめます。
目次
基本の使い方
以下のような構造とします。
<div class="parent">
<div class="child">1番目の要素</div>
<div class="child">2番目の要素</div>
<div class="child">3番目の要素</div>
<div class="child">4番目の要素</div>
<div class="child">5番目の要素</div>
</div>
.parent {
border: 1px solid #000;
padding: 20px;
}
.child {
border: 1px solid #000;
font-size: 16px;
padding: 10px;
margin-bottom: 10px;
}

上からn番目の要素を選択
:nth-child(n)
.child:nth-child(3) {
background-color: #ddd;
}
兄弟要素と比較し、上から数えて3番目の.childの背景色を変更。
これについては後で補足します。

下からn番目の要素を選択
:nth-last-child(n)
.child:nth-last-child(2) {
background-color: #ddd;
}

最初の要素を選択
:first-child
.child:first-child {
background-color: #ddd;
}

最後の要素を選択
:last-child
.child:last-child {
background-color: #ddd;
}

偶数要素を選択
:nth-child(even)を使えば、偶数要素を選択できます。
ちなみに、:nth-child(2n)でも同じことができますので、僕はこっちを使ってます。
.child:nth-child(even) {
background-color: #ddd;
}

奇数要素を選択
:nth-child(odd)を使います。
:nth-child(2n-1)でも同じことができます。
.child:nth-child(odd) {
background-color: #ddd;
}

n個置きに要素を選択
これが意外と便利。
例えば3個置きに要素を選択したい場合は、”:nth-child(3n)”、4個置きの場合は”:nth-child(4n)”のように書きます。
また、”:nth-child(3n-1)”のように書くと、”2,5,8,11,…”という指定もできます。
要するに、nは自動で”0,1,2,3,…”と値が代入され、nの掛け算、引き算、足し算で、要素を選択できるというわけです。
:nth-child(3n-1)の場合、
n = 1 のとき、 :nth-child(1)
n = 2 のとき、 :nth-child(5)
n = 3 のとき、 :nth-child(8)
といった感じで、自動で計算されるというわけです。
便利!
.child:nth-child(3n-1) {
background-color: #ddd;
}

nth-childが参照する要素の範囲に注意
途中にちらっと言いましたが、nth-childは、指定した要素の兄弟要素と比較されます。
つまり、以下のような構造のとき、思わぬ事態が発生します。
<div class="parent">
<h2>グッとくる見出し</h2>
<div class="child">1番目の要素</div>
<div class="child">2番目の要素</div>
<div class="child">3番目の要素</div>
<div class="child">4番目の要素</div>
<div class="child">5番目の要素</div>
</div>
.child:nth-child(3) {
background-color: #ddd;
}

「:nth-child(3)にしてるのに、2番目の要素が選択されている!」
これはなぜかというと、一番上の<h2>もカウントされているからです。
nth-childは、指定したclassだけでなく、兄弟要素全てと比較されます。
つまり、上から3番目なんだけど、一番上は<h2>なので、実質上から3番目の要素である2番目の.childが選択されている状態。
この仕様を知っておかないと、以下のような構造の場合、手間取ってしまうかもしれません。
解決策は2つ。
解決策1:更にブロックで囲む
正直、これがシンプルで構造的にも一番綺麗な解決法だと思います。
<div class="parent">
<h2>グッとくる見出し</h2>
<div class="block">
<div class="child">1番目の要素</div>
<div class="child">2番目の要素</div>
<div class="child">3番目の要素</div>
<div class="child">4番目の要素</div>
<div class="child">5番目の要素</div>
</div>
</div>
childを、blockで囲みました。
まぁ普通こうするよね。
解決策2:nth-of-typeを使う
ちょっとトリッキーな方法となりますが、nth-childの親戚に、nth-of-typeという疑似要素があります。
これはどういうものかというと、例えば以下のような使い方になります。
<div class="parent">
<h2>グッとくる見出し</h2>
<div class="child">1番目の要素</div>
<div class="child">2番目の要素</div>
<div class="child">3番目の要素</div>
<div class="child">4番目の要素</div>
<div class="child">5番目の要素</div>
</div>
.parent div:nth-of-type(3) {
background-color: #ddd;
}

.parent div:nth-of-type(3)と書くと、「.parentの中のdiv」の、上から3番目ということになります。
つまり、比較されるのはdivだけなので、他の要素はカウントされません。
一点、この疑似要素を使う際に注意しなければいけないのは、classをつけたときの挙動。
例えば、
.parent div.child:nth-of-type(3)
と書いた場合、
「parentの中のdiv.childの上から3番目」ではなく、
「parentの中のdivの上から3番目で、かつclassがchildのもの」
という指示になります。
疑似要素自体はclassには使えないので、注意してください。
番外編
あんまりこういうことはないと思うんですが、nth-of-childの応用として、こんなこともできます。
<div class="parent">
<h2>グッとくる見出し</h2>
<p class="text">見出しの次に来るナイスなリード文</p>
<p class="text">リード文の次に来る小粋なジョーク</p>
<h3>匠の粋な計らい</h3>
<p class="text">なんということでしょう、ネタ切れです</p>
</div>
.parent p:nth-of-type(3) {
background-color: #ddd;
}

うーん…使わないなこれ。
まいっか!
以上、現場からでした。

コメントを残す