「n番目の要素」という指定ができる”:nth-child(n)”系の疑似要素ですが、注意しなければいけない点と、案外知られていない便利なバリエーションがあるので、まとめます。
目次
基本の使い方
以下のような構造とします。
1 2 3 4 5 6 7 |
<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> |
1 2 3 4 5 6 7 8 9 10 |
.parent { border: 1px solid #000; padding: 20px; } .child { border: 1px solid #000; font-size: 16px; padding: 10px; margin-bottom: 10px; } |
上からn番目の要素を選択
:nth-child(n)
1 2 3 |
.child:nth-child(3) { background-color: #ddd; } |
兄弟要素と比較し、上から数えて3番目の.childの背景色を変更。
これについては後で補足します。
下からn番目の要素を選択
:nth-last-child(n)
1 2 3 |
.child:nth-last-child(2) { background-color: #ddd; } |
最初の要素を選択
:first-child
1 2 3 |
.child:first-child { background-color: #ddd; } |
最後の要素を選択
:last-child
1 2 3 |
.child:last-child { background-color: #ddd; } |
偶数要素を選択
:nth-child(even)を使えば、偶数要素を選択できます。
ちなみに、:nth-child(2n)でも同じことができますので、僕はこっちを使ってます。
1 2 3 |
.child:nth-child(even) { background-color: #ddd; } |
奇数要素を選択
:nth-child(odd)を使います。
:nth-child(2n-1)でも同じことができます。
1 2 3 |
.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)
といった感じで、自動で計算されるというわけです。
便利!
1 2 3 |
.child:nth-child(3n-1) { background-color: #ddd; } |
nth-childが参照する要素の範囲に注意
途中にちらっと言いましたが、nth-childは、指定した要素の兄弟要素と比較されます。
つまり、以下のような構造のとき、思わぬ事態が発生します。
1 2 3 4 5 6 7 8 |
<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> |
1 2 3 |
.child:nth-child(3) { background-color: #ddd; } |
「:nth-child(3)にしてるのに、2番目の要素が選択されている!」
これはなぜかというと、一番上の<h2>もカウントされているからです。
nth-childは、指定したclassだけでなく、兄弟要素全てと比較されます。
つまり、上から3番目なんだけど、一番上は<h2>なので、実質上から3番目の要素である2番目の.childが選択されている状態。
この仕様を知っておかないと、以下のような構造の場合、手間取ってしまうかもしれません。
解決策は2つ。
解決策1:更にブロックで囲む
正直、これがシンプルで構造的にも一番綺麗な解決法だと思います。
1 2 3 4 5 6 7 8 9 10 |
<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という疑似要素があります。
これはどういうものかというと、例えば以下のような使い方になります。
1 2 3 4 5 6 7 8 |
<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> |
1 2 3 |
.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の応用として、こんなこともできます。
1 2 3 4 5 6 7 |
<div class="parent"> <h2>グッとくる見出し</h2> <p class="text">見出しの次に来るナイスなリード文</p> <p class="text">リード文の次に来る小粋なジョーク</p> <h3>匠の粋な計らい</h3> <p class="text">なんということでしょう、ネタ切れです</p> </div> |
1 2 3 |
.parent p:nth-of-type(3) { background-color: #ddd; } |
うーん…使わないなこれ。
まいっか!
以上、現場からでした。