疑似クラスの nth-of-type と nth-child。
「n 番目の要素だけスタイルを設定したい」場面で良く使用しますが、きちんと理解せずに使用していると、スタイルが正しく適用されてなくてハマってしまうことがあります。
本記事では、nth-of-type と nth-child が効かない原因を丁寧に解説していきます。
この記事でわかることは以下の通りです。
- nth-of-type と nth-child の違い
- nth-of-type と nth-child が効かない原因
nth-of-type の数え方
nth-of-type はその名の通り「type」つまり「型」を見ており、指定した要素だけを数えます。
そのため、ある要素の子要素について、要素の種類ごとに連番を振っているような数え方になります。
<section> <!-- カウント開始の基準となる親要素 -->
<h2>title</h2> <!-- 子要素 h2 の1番目 -->
<p>text</p> <!-- 子要素 p の1番目 -->
<div>div</div> <!-- 子要素 div の1番目 -->
<p>text</p> <!-- 子要素 p の2番目 -->
<div>div</div> <!-- 子要素 div の2番目 -->
<p>text</p> <!-- 子要素 p の3番目 -->
<div>div</div> <!-- 子要素 div の3番目 -->
</section>
nth-of-type を使用するときに、セレクタをクラス名で指定している場合は注意が必要です。
nth-of-type はあくまでも指定した要素を順番にカウントしています。
そのため、セレクタをクラス名で指定しても、「クラス名を順番にカウントしているわけではない」ということです。
詳細は後述しています。
nth-of-type が効かない原因
ここからは実装パターン別に nth-of-type が効かない原因や理由を解説していきます。
また、以下の HTML コードを例にして見ていきます。
<section>
<h2>h2</h2>
<p>first p</p>
<div>first div</div>
<p>second p</p>
<div>second div</div>
<p>third p</p>
<div>third div</div>
</section>
上記コードで nth-of-type を指定していないデフォルトの見た目は、以下の画像の通りです。
セレクタに要素をした場合
例)div:nth-of-type(1)
<section>
<h2>h2</h2>
<p>first p</p>
<div>first div</div>
<p>second p</p>
<div>second div</div>
<p>third p</p>
<div>third div</div>
</section>
div:nth-of-type(1){
color:red;
}
上記コードでは、以下の画像のように div 要素の1番目(first div)に対してスタイルが適用されます。
これは、nth-of-type は要素ごとにカウントしているためです。
例)div:nth-of-type(2)
<section>
<h2>h2</h2>
<p>first p</p>
<div>first div</div>
<p>second p</p>
<div>second div</div>
<p>third p</p>
<div>third div</div>
</section>
div:nth-of-type(2){
color:red;
}
今度は div 要素の2番目(second div)にスタイルを適用してみます。
このように、「div:nth-of-type(2)」では、div 要素だけをカウントしてスタイルを適用しているのが分かると思います。
例)p:nth-of-type(3)
<section>
<h2>h2</h2>
<p>first p</p>
<div>first div</div>
<p>second p</p>
<div>second div</div>
<p>third p</p>
<div>third div</div>
</section>
p:nth-of-type(3){
color:red;
}
次は「p:nth-of-type(3)」で、div 要素ではなく、p 要素にスタイルを適用してみます。
上記コードでは、以下の画像のように p 要素の3番目(third p)だけスタイルが適用されています。
セレクタにクラス名をした場合
セレクタにクラス名を指定した場合は注意が必要です。
前述したように、セレクタをクラス名で指定しても、「クラス名を順番にカウントしているわけではない」ということです。
これを頭に入れておかないと、nth-of-type の罠にハマってしまいます。
今度は、以下の HTML コードを参考に解説していきます。
p 要素と div 要素の1番目と2番目にクラス名「hoge」を指定しています。
p 要素と div 要素の3番目と、h2 要素にはクラス名を指定していません。
<section>
<h2>h2</h2>
<p class="hoge">first p</p>
<div class="hoge">first div</div>
<p class="hoge">second p</p>
<div class="hoge">second div</div>
<p>third p</p>
<div>third div</div>
</section>
デフォルトの見た目は変わらず、以下の通りです。
例).hoge:nth-of-type(2)
<section>
<h2>h2</h2>
<p class="hoge">first p</p>
<div class="hoge">first div</div>
<p class="hoge">second p</p>
<div class="hoge">second div</div>
<p>third p</p>
<div>third div</div>
</section>
.hoge:nth-of-type(2) {
color: red;
}
上記コードの場合、以下の画像のようになります。
直感的なイメージでは、「.hoge:nth-of-type(2)」とすると、クラス名が「hoge」になっている2番目の要素(first div)にスタイルが適用されそうです。
ですが、実際は、p 要素の2番目(second p)と div 要素の2番目(second div)にスタイルが適用されました。
これは、何度も書きますが、nth-of-type はクラス名単位で数えているわけではなく、要素単位で数えているのが原因です。
「.hoge:nth-of-type(2)」とした場合、各要素の2番目で、かつ、クラス名が一致している物がスタイル適用候補になります。
この例では、p 要素と div 要素それぞれの2番目で、かつ、クラス名が「hoge」になっている要素(second p と second div)に対してスタイルが適用されるわけです。
このように、クラス名で nth-of-type を使用する場合は注意が必要です。
あくまでも、nth-of-type は要素単位でしかなく、クラス単位で数えているわけではないということです。
例).hoge:nth-of-type(3)
<section>
<h2>h2</h2>
<p class="hoge">first p</p>
<div class="hoge">first div</div>
<p class="hoge">second p</p>
<div class="hoge">second div</div>
<p>third p</p>
<div>third div</div>
</section>
.hoge:nth-of-type(3) {
color: red;
}
上記コードの場合、以下の画像のように、どの要素にもスタイルが適用されなくなりました。
これは、「.hoge:nth-of-type(3)」としているため、各要素の3番目がスタイル適用候補になります。
つまり、p 要素と div 要素それぞれの3番目(third p と third div)が候補になりますが、クラス名が「hoge」ではないため、スタイルが適用されていません。
nth-child の数え方
今度は、nth-child の数え方や効かない原因を以下に解説していきます。
nth-child は、nth-of-type とは違って要素ごとにカウントしません。
ある要素の子要素を上から順番に単純にカウントするだけです。
<section> <!-- カウント開始の基準となる親要素 -->
<h2>title</h2> <!-- 子要素の1番目 -->
<p>text</p> <!-- 子要素の2番目 -->
<div>div</div> <!-- 子要素の3番目 -->
<p>text</p> <!-- 子要素の4番目 -->
<div>div</div> <!-- 子要素の5番目 -->
<p>text</p> <!-- 子要素の6番目 -->
<div>div</div> <!-- 子要素の7番目 -->
</section>
nth-child が効かない原因
nth-of-type と同様に、ここからは実装パターン別に nth-child が効かない原因や理由を解説していきます。
また、以下の HTML コードを例にして見ていきます。
<section>
<h2>h2</h2>
<p>first p</p>
<div>first div</div>
<p>second p</p>
<div>second div</div>
<p>third p</p>
<div>third div</div>
</section>
nth-child で何も指定してないデフォルトの見た目は以下です。
セレクタに要素をした場合
例)p:nth-child(2)
<section>
<h2>h2</h2>
<p>first p</p>
<div>first div</div>
<p>second p</p>
<div>second div</div>
<p>third p</p>
<div>third div</div>
</section>
p:nth-child(2) {
color: red;
}
上記コードの場合は、以下の画像のようになります。
上記画像のように、p 要素の2番目ではなく、全ての子要素内の2番目要素にスタイルが適用されます。
つまり、「p:nth-child(2)」では、全体の子要素の2番目で、かつ、p 要素の物(first p)が対象になるということです。
このように、nth-child は nth-of-type と違って要素ごとのカウントではなく、全子要素を単純にカウントしているということです。
例)div:nth-child(2)
<section>
<h2>h2</h2>
<p>first p</p>
<div>first div</div>
<p>second p</p>
<div>second div</div>
<p>third p</p>
<div>third div</div>
</section>
div:nth-child(2) {
color: red;
}
上記コードだと、以下の画像のように、どの要素にもスタイルが適用されていません。
これは、全体の子要素内の2番目は p 要素であり、div 要素ではないのでスタイルが適用されないためです。
セレクタにクラス名をした場合
セレクタにクラス名を指定した場合は注意が必要です。
nth-of-type の場合と同様に、今度は、以下の HTML コードを参考に解説していきます。
p 要素と div 要素の1番目と2番目にクラス名「hoge」を指定しています。
p 要素と div 要素の3番目と、h2 要素にはクラス名を指定していません。
<section>
<h2>h2</h2>
<p class="hoge">first p</p>
<div class="hoge">first div</div>
<p class="hoge">second p</p>
<div class="hoge">second div</div>
<p>third p</p>
<div>third div</div>
</section>
デフォルトの見た目は変わらず、以下の通りです。
例).hoge:nth-child(2)
<section>
<h2>h2</h2>
<p class="hoge">first p</p>
<div class="hoge">first div</div>
<p class="hoge">second p</p>
<div class="hoge">second div</div>
<p>third p</p>
<div>third div</div>
</section>
.hoge:nth-child(2) {
color: red;
}
上記コードだと、以下の画像のようになります。
nth-of-type と同様に、nth-child もクラス名を指定する場合は注意が必要です。
直感的なイメージでは、「.hoge:nth-child(2)」とすると、クラス名が「hoge」になっている2番目の要素(first div)にスタイルが適用されそうです。
ですが、「.hoge:nth-child(2)」とした場合、全体の子要素の2番目要素で、かつ、クラス名が一致している物がスタイル適用候補になります。
この例では、2番目、かつ、クラス名が「hoge」になっている要素(first p)に対してスタイルが適用されるわけです。
例).hoge:nth-child(3)
<section>
<h2>h2</h2>
<p class="hoge">first p</p>
<div class="hoge">first div</div>
<p class="hoge">second p</p>
<div class="hoge">second div</div>
<p>third p</p>
<div>third div</div>
</section>
.hoge:nth-child(3) {
color: red;
}
上記コードだと、以下の画像のようになります。
全体の子要素の3番目、かつ、「hoge」のクラス名が付いている div 要素(first div)に対してスタイルが適応されています。
例).hoge:nth-child(6)
<section>
<h2>h2</h2>
<p class="hoge">first p</p>
<div class="hoge">first div</div>
<p class="hoge">second p</p>
<div class="hoge">second div</div>
<p>third p</p>
<div>third div</div>
</section>
.hoge:nth-child(6) {
color: red;
}
上記コードでは、以下の画像のようになります。
「.hoge:nth-child(6)」とした場合は全体の子要素の6番目(third p)が対象になりますが、「hoge」のクラス名が付いていないので、スタイルが適用されていません。
まとめ
最後にまとめておきます。
- nth-of-type は要素単位でカウントする(セレクタをクラス名で指定してもクラス単位ではない)
- nth-child は子要素全てをカウントする