CSS:クラス名にnth-of-type, nth-child を指定する場合の注意

CSSの擬似クラス、nth-of-type は nth-child とともにリストの中の何番目などと指定する場合によく使います。その2つの違いは理解していても、クラス名に対して指定する場合は要注意です。今回ハマったケースがありますので整理してみます。



nth-of-type と nth-child の違い

まず、この2つの違いを整理しておきます。


どちらも指定した要素の親要素から見た順番で、nth-of-type は兄弟要素のうち同じ要素のみ数え、nth-child は要素の種類関係なく兄弟要素すべてを数えます。


<div>
  <div>1つ目</div>   <!-- div:nth-child(1) または div:nth-of-type(1) -->
  <p>2つ目</p>         <!-- p:nth-child(2) または p:nth-of-type(1) -->
  <p>3つ目</p>         <!-- p:nth-child(3) または p:nth-of-type(2) -->
  <div>4つ目</div>   <!-- div:nth-child(4) または div:nth-of-type(2) -->
  <p>5つ目</p>         <!-- p:nth-child(5) または p:nth-of-type(3) -->
</div>


nth-child の場合は、上から 1, 2, 3… と並んでいる通り、要素が div でも p でもすべての要素を数えます。それに対して nth-of-type は div の場合は div だけ、p の場合は p だけ数えます。

nth は何番目という意味ですので、nth-child は子の何番目、nth-of-type は同じタイプの何番目ということになります。


クラス名で指定する場合

で、今回ハマったケースですが、この擬似クラスはあくまでも要素に対する指定であり、クラス名で指定した場合でもそのクラス名を指定したその要素を数えますのでクラス名はあくまでも二次的になるということです。


nth-child の場合

<div>
  <p class="hoge">1つ目</p>  <!-- .hoge:nth-child(1) -->
  <p class="hoge">2つ目</p>  <!-- .hoge:nth-child(2) -->
  <p class="fuga">3つ目</p>  <!-- .fuga:nth-child(1) ではなく .fuga:nth-child(3) -->
  <p class="fuga">4つ目</p>  <!-- .fuga:nth-child(2) ではなく .fuga:nth-child(4) -->
  <p class="fuga">5つ目</p>  <!-- .fuga:nth-child(3) ではなく .fuga:nth-child(5) -->
</div>


まず、nth-child の場合はクラス名で指定してもすべての子要素を数えますので、子が同じ要素であれば事実上クラス名で指定する意味がありません。

  • 「3つ目」を指定しようとして .fuga:nth-child(1) としても「1つ目」を指し、クラス名が .fuga ではありませんので無視されます
  • 「5つ目」を指定しようとして .fuga:nth-child(3) としますと「3つ目」を指し、クラス名が .fuga ですので「3つ目」に適応されます


子要素に div などが混在している場合は、子要素の順番である引数とクラス名が合っていれば順番通り適応されますし、合っていない場合は無視されます。


nth-of-type の場合

<div>
  <p class="hoge">1つ目</p>    <!-- .hoge:nth-of-type(1) -->
  <p class="fuga">2つ目</p>    <!-- .fuga:nth-of-type(1) ではなく .fuga:nth-of-type(2) -->
  <p class="fuga">3つ目</p>    <!-- .fuga:nth-of-type(2) ではなく .fuga:nth-of-type(3) -->
  <div class="hoge">4つ目</div><!-- .hoge:nth-of-type(1) は1つ目を上書き -->
  <p class="hoge">5つ目</p>    <!-- .hoge:nth-of-type(2) ではなく .hoge:nth-of-type(4) -->
</div>


  • 「2つ目」を指定しようとして .fuga:nth-of-type(1) としても p の1番目を指し .fuga ではありませんので無視されます
  • 「3つ目」を指定しようとして .fuga:nth-of-type(2) としますと p の2番めかつ .fuga の「2つ目」を指します
  • 「4つ目」を指定しようとして .hoge:nth-of-type(1) としますと「1つ目」を指し、この例ではクラス名だけで「4つ目」を指定することはできません
  • 「5つ目」を指定しようとして .hoge:nth-of-type(2) としても p の2番めを指し .hoge ではありませんので無視されます


と、書いていても混乱します。間違っていたら指摘してください 。結局、クラス名だけで nth-of-type や nth-child を使うのはやめたほうがいいということだと思います。