:nth-child()の使い方を極める〜CSS3疑似クラス

HTML&CSS
スポンサーリンク

:nth-child() 擬似クラスについて

:nth-child() 擬似クラスの仕様として、W3CのRecommendation仕様書(日本語訳)には以下のように記されています。

6.6.5.2. :nth-child() 擬似クラス

:nth-child(an+b) 擬似クラスは、文書ツリーにおいて、ある要素の子で、その前に an+b-1 個 (n は正の整数もしくは0) の兄弟を持つ状態を表す。a と b が正の数である場合、擬似クラスは要素の子を a 個ずつのグループに分け (最後のグループは余りを持つ)、それぞれのグループから b 番目の要素を選択する。この擬似クラスによりたとえば、表において行ごとを選択することや、4つの段落をひとつのグループとし、グループ内の段落それぞれに異なる色を与えることなどができる。a と b の値は整数 (正、負、もしくは0) でなければならない。最初の子要素のインデックスは1となる。

日本語訳を読んでもなんだかよくわかりません。
簡単に説明すると次のようになります。

E:nth-child(n)は、疑似クラスのひとつです。
n番目の子となるE要素にスタイルを適用する際に使用します。

:nth-child() の簡単な例

:nth-child() の簡単なサンプル
これは2番目のliに赤のボーダーをつけます。

HTMLコード

<ul>
  <li>aaaaa</li>
  <li>bbbb</li>
  <li>ccccc</li>
</ul>

CSSコード

li:nth-child(2){
  border:1px solid red;
}

次のようなHTML構造だと少し戸惑います。どの文字に赤いボーダーが入るでしょうか?
簡単なサンプルで勉強した場合は、eeeeeと答えてしまいがちですが、実はcccccに赤いボーダーがつきます。
:nth-child() の間違いやすいサンプル
HTMLコード

<div>
  <h1>aaaaa</h1>
  <h2>bbbb</h2>
  <p>ccccc</p>
  <p>ddddd</p>
  <p>eeeee</p>
</div>

CSSコード

p:nth-child(3){
  border:1px solid red;
}

この状態がW3Cの仕様書に書かれている次の部分にあたります。

擬似クラスは、文書ツリーにおいて、ある要素の子で、その前に an+b-1 個 (n は正の整数もしくは0) の兄弟を持つ状態を表す。

「ある要素」はdivです。その子要素が h1, h2, p にあたります。
an+b-1 個 は()の中の3です。
つまり、p:nth-child(3)のことを意味します。
最初の子要素のインデックスは1ですから、最初から3番目のp要素cccccでマッチするわけです。
もう少し詳しく書くなら「ある要素の中にいる兄弟要素の3番目の兄弟でしかもp要素のもの」この条件に合う要素がマッチすることになるのです。
兄弟間にどんな要素があっても関係ないのがnth-child()の特徴です。さらに、もし3番目にp要素がなければマッチは起こらずにボーダーは適用されません。

それでは、CSSの「p:nth-child(3)」の設定はそのままで、HTMLを以下のように変更すると赤いボーダーはどこにつくでしょうか?
サンプル
HTMLコード

<div>
  <h1>aaaaa</h1>
  <h2>bbbb</h2>
  <p>ccccc</p>
  <div>
    <p>ddddd</p>
    <p>fffffffff</p>
    <p>ggggggg</p>
 </div>
  <p>eeeee</p>
</div>

これも上の例と同様に考えます。この場合は「ある要素の子」が外側のdivの子要素であり、入れ子状態のdiv要素にもあてはまります。
つまり入れ子状態ができるに従って「ある要素の子」は複数登場してしまうことになるのです。
このような入れ子状態の場合はp:nth-child(3)に複数マッチすることが考えられます。

結果としてはcccccとgggggggに赤いボーダーがつきます。
入れ子状態になる構造の場合はセレクターをしっかりと考えてないと予期せぬ結果が起こることになります。

全称セレクタを活用した方法

次に変わったセレクタの指定方法をみてみましょう。
疑似クラスのコロンの前に半角英数のスペースをひとつ入れています。

セレクタがdivの後に半角スペースを一つ入れてから:nth-child(3)の記述をしています。
どのような結果になるか少し考えてみてください。

サンプル
HTMLコード

<div>
  <h1>aaaaa</h1>
  <h2>bbbb</h2>
  <p>ccccc</p>
  <p>ddddd</p>
  <p>eeeee</p>
</div>

CSSコード

div :nth-child(3){
  border:1px solid red;
}

そもそもこの例ではdivに兄弟要素はないし、これはボーダーが付かないと考えてしまいます。
けれども答えはサンプルのようにcccccに赤いボーダーがつきます。

さて、この挙動ですが、CSSのセレクタの設定にポイントがあります。
divと:nth-child(3)の間に半角スペースが入っています。ココの半角スペースがポイントです。

ここの半角スペースはアスタリスク(*)、つまり全称セレクタが省略されていると認識されます。
つまり「 div *:nth-child(3) 」と同等に意味になります。

そのため、div要素の子孫要素すべての要素の中で3番目の要素という解釈になるわけです。
その結果3番目の要素がどんなタグでもマッチすることになります。
サンプル

*教科書で使用している「HTML&CSS標準デザイン講座」、またその新版の本でも「nth-child()」の説明が全てこの記述になっています。おそらく独学の方にとっては混乱のもとになると思われます。半角スペースを使ったdiv :nth-child(3)の意味がきちんと説明されていませんので、誤解を生みやすくなっています。注意してください。

:nth-child(an+b)の使い方

:nth-child(an+b)のan+bを使用してみましょう。
:nth-child(n)として()の中をnとすると0から1ずつ数字が入りセレクタで指定した要素の数全てがマッチします。
サンプル
HTMLコード

<ul>
  <li>aaaaa</li>
  <li>bbbb</li>
  <li>ccccc</li>
  <li>dddd</li>
  <li>eeeee</li>
  <li>ffffffff</li>
  <li>ggggg</li>
  <li>hhhhh</li>
  <li>iiiiiiiiiii</li>
  <li>jjjjjjjjjj</li>
</ul>

CSSコード

li:nth-child(n){
border:1px solid red;
}

nの使い方は以上のようになります。これをうまく利用するとさまざまな要素とマッチングができます。
例えば2nとすれば2の倍数とマッチング(偶数)、3nとすれば3の倍数とマッチングします。

偶数奇数

偶数は :nth-child(2n)
偶数サンプル
奇数は :nth-child(2n+1)
奇数サンプル
で表されます。nは0か正の整数です。つまり0,1,2,3,4,5,6,・・・・となります。
偶数、奇数を指定する場合はキーワードも用意されています。
偶数は :nth-child(even)
evenサンプル
奇数は :nth-child(odd)

oddサンプル

:nth-child(an+b)のb値を使ってみる

an+bのb値を設定するとbの値以上にマッチングします。
サンプル
HTMLコード

<ul>
  <li>aaaaa</li>
  <li>bbbb</li>
  <li>ccccc</li>
  <li>dddd</li>
  <li>eeeee</li>
  <li>ffffffff</li>
  <li>ggggg</li>
  <li>hhhhh</li>
  <li>iiiiiiiiiii</li>
  <li>jjjjjjjjjj</li>
</ul>

CSSコード

li:nth-child(n+5){
border:1px solid red;
}

-an+bとして-aの値を設定するとbの値以下にマッチングします。
:nth-child(-an+b)
サンプル

li:nth-child(-n+5){
border:1px solid red;
}

nth-child

タイトルとURLをコピーしました