S 構文を使用して :nth-child() の選択をより詳細に制御

An+B ロジックを適用する前に、子要素のセットを事前フィルタします。

:nth-child() 疑似クラス セレクタと :nth-last-child() 疑似クラス セレクタ

:nth-child() 疑似クラス セレクタを使用すると、インデックスで DOM 内の要素を選択できます。An+B マイクロ構文を使用すると、選択する要素を細かく制御できます。

  • :nth-child(2): 2 番目の子を選択します。
  • :nth-child(2n): 偶数の子要素 (2 番目、4 番目、6 番目、8 番目など)をすべて選択します。
  • :nth-child(2n+1): 奇数の子要素をすべて選択します(1 番目、3 番目、5 番目、7 番目など)
  • :nth-child(5n+1): 1 番目(=(5×0)+1)、6 番目(=(5×1)+1)、11 番目(=(5×2)+1)の子を選択します。
  • :nth-child(5n+2): 2 番目 (=(5×0)+2)、7 番目 (=(5×1)+2)、12 番目 (=(5×2)+2)、… の子を選択します。

ただし、A パラメータを省略すると、より多くのクリエイティブを選択できます。次に例を示します。

  • :nth-child(n+3): 3 番目以降のすべての子を選択します(3 番目、4 番目、5 番目など)
  • :nth-child(-n+5): 5 番目までのすべての子要素(1 番目、2 番目、3 番目、4 番目、5 番目)を選択します。

これらの :nth-child() 選択を組み合わせると、要素の範囲を選択できます。

  • :nth-child(n+3):nth-child(-n+5): 3 番目から 5 番目までの子要素 (3 番目、4 番目、5 番目)を選択します。

:nth-last-child() を使用すると同様の選択ができますが、先頭からカウントするのではなく、末尾からカウントします。

of S 構文を使用した選択の事前フィルタリング

CSS セレクタ レベル 4 の新機能として、セレクタ リストを :nth-child():nth-last-child() に任意で渡せるようになりました。

:nth-child(An+B [of S]?)
:nth-last-child(An+B [of S]?)

of S が指定されている場合、An+B ロジックは、指定されたセレクタ リスト S と一致する要素にのみ適用されます。これは、基本的に An+B が処理を行う前に子を事前フィルタリングできることを意味します。

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 9.

たとえば、:nth-child(2 of .highlight) は、.highlight クラスを持つ 2 番目の一致要素を選択します。つまり、クラス .highlight を持つすべての子要素のうち、2 番目の要素を選択します。

これは、クラス .highlight を持ち、2 番目の子でもある要素を選択する .highlight:nth-child(2) とは対照的です。

以下のデモで、この違いを確認できます。

  • :nth-child(2 of .highlight) に一致する要素がピンク色の枠線で囲まれています。
  • .highlight:nth-child(2) に一致する要素の枠線が緑色になります。

S はセレクタ リストであるため、カンマで区切られた複数のセレクタを受け入れます。たとえば、:nth-child(4 of .highlight, .sale) は、兄弟要素のセットから .highlight または .sale のいずれかである 4 番目の要素を選択します。

次のデモでは、:nth-child(4 of .highlight, .sale) に一致する要素にオレンジ色の枠線が適用されています。

ゼブラストライプ、再考

:nth-child() が使用される典型的な例は、ストライプ テーブルを作成する場合です。テーブルの各行の色を交互に表示する視覚的な手法です。通常、この問題は次のように解決します。

tr:nth-child(even) {
  background-color: lightgrey;
}

これは静的テーブルでは問題なく機能しますが、テーブルの内容を動的にフィルタリングし始めると問題が発生します。たとえば、2 行目を非表示にすると、1 行目と 3 行目が同じ背景色で表示されます。

この問題を解決するには、An+B ロジックから非表示の行を除外することで、:nth-child(An+B [of S]?) を活用します。

tr:nth-child(even of :not([hidden])) {
  background-color: lightgrey;
}

これは非常に便利です。

写真: Markus SpiskeUnsplash