CSS3の便利なセレクタをおさらい、「:nth-child()」と「:nth-of-type()」疑似クラスの使い方
Post on:2016年9月27日
「:nth-child()」と「:nth-of-type()」セレクタは、他の単純なセレクタでは表現できないドキュメントツリー内の情報に基づいて要素を選択することを可能にする構造的な擬似クラスです。
この2つの疑似クラスは非常に似ていますが、基本的に異なる方法で機能します。その仕組みを確認しておきましょう。
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
:nth-child()がどのように機能するか
nth-child()擬似クラスは、それの兄弟の中での要素の位置をあらわす数に基づいて要素を一致させるために使用されます。具体的には、その数はドキュメントツリー(-1)内の要素の前に存在する兄弟の数(n番目)をあらわします。
この数は「an+b」と指定でき、「n」はインデックスで、「a」と「b」は任意の整数です。例えば、すべての要素を選択するためには、下記のように指定します。
1 2 3 |
:nth-child(1n+0) { /* スタイルを記述 */ } :nth-child(n+0) { /* スタイルを記述 */ } :nth-child(1n) { /* スタイルを記述 */ } |
この機能を使用することに加えて、わたし達は「:nth-child(1)」のように単一の整数値、または「odd」「even」のようにキーワードを使用することが可能です。
1 2 3 4 5 |
:nth-child(odd) { /* 奇数の要素のスタイルを記述 */ } :nth-child(2n+1) { /* 奇数の要素のスタイルを記述 */ } :nth-child(even) { /* 偶数の要素のスタイルを記述 */ } :nth-child(2n+0) { /* 偶数の要素のスタイルを記述 */ } |
「:nth-child()」を自身に使用する時は、どの要素が選択されるか予測することは簡単です。例えば、下記のマークアップを例に見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 |
<div class="example"> <p>This is a <em>paragraph</em>.</p> <p>This is a <em>paragraph</em>.</p> <p>This is a <em>paragraph</em>.</p> <div>This is a <em>divider</em>.</div> <div>This is a <em>divider</em>.</div> <!-- 選択したい要素 --> <p>This is a <em>paragraph</em>.</p> <p>This is a <em>paragraph</em>.</p> <div>This is a <em>divider</em>.</div> <p>This is a <em>paragraph</em>.</p> <div>This is a <em>divider</em>.</div> </div> |
5番目のdiv要素を選択するのであれば、下記のように指定します。
1 |
.example :nth-child(5) { background: #ffdb3a; } |
しかし要素にpやdivなど複数のタイプがあると、予期しない結果が発生する可能性があります。その場合は、タイプやクラスセレクタで「:nth-child()」擬似クラスを結合します。
今度はdiv要素のn番目として指定してみましょう。
下記のように指定したくなると思います。
1 |
.example div:nth-child(2) { background: #ffdb3a; } |
この指定がうまく機能しない理由は、セレクタがターゲットに定めている要素は実際には存在しないためです。上記のセレクタを使用した際に、ユーザーエージェントは次の手順で進みます。
- .exampleのすべての子要素を選択。
- タイプにかかわらず、そのリストで2番目の要素を検索。
- その要素がdiv要素であるかどうかを確認。
ドキュメントツリーの2番目の要素はパラグラフです、div要素ではないので、何も選択されません。もし2番目のdiv要素を選択するのであれば、「:nth-of-type()」疑似クラスを使用しなければならないでしょう。
:nth-of-type()がどのように機能するか
「:nth-of-type()」は「:nth-child()」のように、数に基づいて要素を一致させるために使用されます。しかしながら、その数はタイプが同じ要素である兄弟の中だけから要素のポジションをあらわします。
数は関数のように表現するか、偶数または奇数のキーワードを使用することができます。さきほどのマークアップを使って、奇数番目のp要素を指定してみましょう。
1 |
.example p:nth-of-type(odd) { background: #ffdb3a; } |
上記のセレクタを使用した際に、ユーザーエージェントは次の手順で進みます。
- タイプがpである.examplesのすべての子要素を選択。
- これらの要素だけの新しいリストを作成。
- そのリストから奇数番目を選択。
そのため、さきほどうまく機能しなかった.exampleの子要素の2番目のdiv要素、つまり全体の5番目の子要素を選択することができます。
1 |
.example div:nth-of-type(2) { /* スタイルを記述 */ } |
他にもある便利な「nth」疑似クラス
「:nth-child()」と「:nth-of-type()」の他にも、兄弟内での位置に基づいて要素を選択するために使用できる構造的擬似クラスがあります。2つのグループに分類され、1つは「:nth-child()」のようにタイプに依存しないもの、もう1つは「:nth-of-type()」のようにタイプに依存するものです。
左: 要素のタイプに依存しないもの、右: 依存するもの
後ろから数える: nth-last-child() と nth-last-of-type()
この2つの擬似クラスは「:nth-child()」と「:nth-of-type()」のように動作しますが、最初の兄弟のグループ内の最後の要素から数え始めます。
1 2 |
.example :nth-last-child(1) { background: #a6cae7; } .example p:nth-last-of-type(1) { background: #ffdb3a; } |
最初の要素: first-child() と first-of-type()
この2つの擬似クラスは最初の要素を選択します。これらは「:nth-child()」と「:nth-of-type()」擬似クラスを使用して、単に1の値を渡すと考えることができます。
1 2 3 4 5 |
.example :first-child() { /* スタイルを記述 */ } .example :nth-child(1) { /* スタイルを記述 */ } /* 上と同じです */ .example :first-of-type() { /* スタイルを記述 */ } .example :nth-of-type(1) { /* スタイルを記述 */ } /* 上と同じです */ |
最後の要素: last-child() と last-of-type()
最初の要素の2つと反対の役割です。これらは「:nth-last-child()」と「:nth-last-of-type()」擬似クラスを使用して、1の値を渡すと考えることができます。
1 2 3 4 5 |
.example :last-child() { /* スタイルを記述 */ } .example :nth-last-child(1) { /* スタイルを記述 */ } /* 上と同じです */ .example :last-of-type() { /* スタイルを記述 */ } .example :nth-last-of-type(1) { /* スタイルを記述 */ } /* 上と同じです */ |
唯一の要素: only-child() と only-of-type()
最後に、これらの擬似クラスは唯一の子要素を選択します。
「:only-child()」はタイプに関係なく、親要素の文字通り唯一の子でなければなりません。
「:only-of-type()」はそのタイプの唯一の子であることのみを必要とします。
1 2 3 |
.example :only-child() { /* スタイルを記述 */ } .example p:only-of-type() { /* スタイルを記述 */ } |
sponsors