シリーズ「CSS セレクタのレシピ」では、CSS セレクタのテクニックを紹介していきます。
CSS は開発のサイクルを活発にするために、モジュール単位で仕様が策定されています。セレクタに関しては、現時点では 2018 年 11 月に勧告(Recommendation)された「Selectors Level 3」がスタンダードですが、Working Draft の「Selectors Level 4」のいくつかの機能も、主要ブラウザではすでにサポートされています。
この記事では、:nth-child()
や :nth-last-child()
のように、擬似クラスに -child
が付く「子要素インデックス1」の、「Selectors Level 4」まで含めた CSS セレクタのテクニックとその仕組みを説明してきます。
- 紹介するセレクタには複雑な記法を含みますが、直感的に理解できないセレクタはメンテナンス性を損なうので、他に手段がない場合にのみ限定的に使うようにしましょう。
- 加えて、役割がわかるようにコードにコメントを残しておくとよいかもしれません。
凡例
見出し「凡例」この記事のサンプルの見た目と、ベースとなる HTML コードは以下です。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
この HTML の、最初のリスト項目(.item
)にスタイルを加えると、以下の見た目になります。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
それでは、これらのフォーマットをもとに、CSS セレクタのレシピを紹介していきます。
最初から n 番目まで
見出し「最初から n 番目まで」以下は、.item
の最初から 3 番目までの要素にスタイルを指定する例です。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
n
には 0
から始まる整数が入るので、-0 + 3 = 3
、-1 + 3 = 2
、-2 + 3 = 1
となり、3 番目から最初の要素までが対象となります。
最後から n 番目まで
見出し「最後から n 番目まで」以下は、.item
の最後から 3 番目までの要素にスタイルを指定する例です。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
こちらは前述の「最初から n 番目まで」の応用で、:nth-last-child()
擬似クラスを使用することで、後方から参照しています。
n 番目から最後まで
見出し「n 番目から最後まで」以下は、.item
の 4 番目から最後までの要素にスタイルを指定する例です。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
n
には 0
から始まる整数が入るので、0 + 4 = 4
、1 + 4 = 5
、2 + 4 = 6
… と続いていくため、4 番目から最後までの要素が対象となります。
また、最初の子要素以外にマージンを付けるケースがよくありますが、そのときに :nth-child(n+2)
が使用できます。
n 番目から最初まで
見出し「n 番目から最初まで」以下は、.item
の後ろから数えて 4 番目から最初までの要素にスタイルを指定する例です。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
こちらは前述の「n 番目から最後まで」の応用で、:nth-last-child()
擬似クラスを使用することで、後方から参照しています。
また、最後の子要素以外にマージンを指定するときに :nth-last-child(n+2)
が使用できます。
n 番目から n 番目まで
見出し「n 番目から n 番目まで」以下は、.item
の 4 番目から 7 番目までの要素にスタイルを指定する例です。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
こちらは「n 番目から最後まで」と「最初から n 番目まで」を組み合わせた記法です。
要素数が n と一致
見出し「要素数が n と一致」以下は、.item
の要素数が 5 のときにスタイルを指定する例です。
1 番目のサンプルは要素数が 4 のため、スタイルが適用されません。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- 5
この記法では、まず、:first-child
(最初の要素)と :nth-last-child(5)
(最後から 5 番目の要素)が同一であることが条件となります。
また、セレクタが ,
(カンマ)でリスト化され、重複した指定になるので冗長に感じますが、それぞれ以下の役割を担っています。
- 1 行目:
.item:first-child:nth-last-child(5)
は、最初の要素を選択 - 2 行目:
.item:first-child:nth-last-child(5) ~ .item
は、~
(チルダ)で接合することで、最初の要素を除いた 2 番目以降の要素を選択
これらの指定の組み合わせにより、要素数が 5 のときにのみ、すべての要素にスタイルを適用することができます。
要素数が n 以上
見出し「要素数が n 以上」以下は、.item
の要素数が 5 以上のときにスタイルを指定する例です。
1 番目のサンプルは要素数が 4 のため、スタイルが適用されません。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- 5
こちらは前述の「要素数が n と一致」の応用で、(n+5)
とすることで、要素数が 5 以上のときに対象となります。
要素数が n 以下
見出し「要素数が n 以下」以下は、.item
の要素数が 5 以下のときにスタイルを指定する例です。
1 番目のサンプルは要素数が 6 のため、スタイルが適用されません。
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
こちらも「要素数が n と一致」の応用で、(-n+5)
とすることで、要素数が 5 以下のときに対象となります。
要素数が n 以上 n 以下
見出し「要素数が n 以上 n 以下」以下は、.item
の要素数が 5 以上 7 以下のときにスタイルを指定する例です。
1 番目、2 番目のサンプルは要素数がこの範囲に収まらないため、スタイルが適用されません。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
こちらは「要素数が n 以上」と「要素数が n 以下」を組み合わせた記法です。
セレクタが複雑になり、直感的ではないため、むやみに使うのは避けた方がよいでしょう。
要素数が奇数
見出し「要素数が奇数」以下は、.item
の要素数が奇数のときにスタイルを指定する例です。
1 番目のサンプルは要素数が偶数のため、スタイルが適用されません。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
「要素数が n と一致」の応用で、(2n+1)
とすることで、要素数が奇数のときに対象となります。
要素数が偶数
見出し「要素数が偶数」以下は、.item
の要素数が偶数のときにスタイルを指定する例です。
1 番目のサンプルは要素数が奇数のため、スタイルが適用されません。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
「要素数が n と一致」の応用で、(2n)
とすることで、要素数が偶数のときに対象となります。
特定の属性値の n 番目
見出し「特定の属性値の n 番目」以下は、特定の属性値の n 番目にスタイルを指定する例です。
このサンプルでは以下のように、要素ごとに a
、b
、c
のクラスを付与しています。
このとき、.a
を持つ 3 番目の要素にスタイルを指定するには、以下のコードで実現できます。
- A
- B
- C
- A
- B
- C
- A
- B
- C
- A
このように、:nth-child()
擬似クラスで of S
を使うことで2、特定の属性値が付与された要素の n 番目を指定することができます。
なお、この of S
を使用した Selectors Level 4 の記法は、現時点では主要ブラウザのなかで Firefox が非対応ですが、次期バージョンの 113 よりサポートされる予定です3。
フィルタに対応したストライプ
見出し「フィルタに対応したストライプ」以下は :nth-child(even)
で、偶数番目の要素のみにストライプのスタイルを付けた例ですが、フィルタ機能によって一方の要素を hidden
属性によって非表示にすると、ストライプのパターンが変わってしまいます。
- A
- B
- A
- A
- A
- B
- B
- B
- A
- A
この問題を解消するには、フィルタ実行時に JS で調整する方法が考えられますが、:nth-child(even of :not([hidden]))
の記法により、CSS のみで実現することができます。
例えば、フィルタの選択を「A」にすると、「B」に hidden
属性が付与されますが、:nth-child(even of :not([hidden]))
によって、hidden
属性が指定された要素以外の偶数番目(even
)の要素を対象とすることができます。
このテクニックは、ゼブラストライプ(zebra striping)と呼ばれる、表組み(table
要素)の行に対して交互に色を指定したときに、フィルタ機能を付与したケースで特に有効です。
No. | カテゴリ |
---|---|
1 | Apple |
2 | Banana |
3 | Apple |
4 | Apple |
5 | Apple |
6 | Banana |
7 | Banana |
8 | Banana |
9 | Apple |
10 | Apple |
また、それ以外のケースとして、記事ページの最後に関連する記事一覧を表示するときに、見ているページの記事(自分自身)を非表示にするコードを書くことがありますが、その場合にも使うことができそうです。
なお、こちらも of S
を使用した Selectors Level 4 の記法なので、現時点では主要ブラウザのなかで Firefox が非対応ですが、次期バージョンの 113 よりサポートされる予定です3。
参考文献
見出し「参考文献」本記事の作成にあたり、以下のウェブページや書籍を参考にしました。
- Child-indexed Pseudo-classes | Selectors Level 4 | W3C(外部リンクを開く)
- More control over :nth-child() selections with the of S syntax - Chrome Developers | Chrome Developers(外部リンクを開く)
- 『今すぐ使えるCSSレシピブック』(著者:たかもそ、出版:C&R研究所)(外部リンクを開く)
- 『CSSシークレット』(著者:Lea Verou、訳者:牧野 聡、出版:オライリージャパン)(外部リンクを開く)
脚注
-
W3C 仕様書における「Selectors Level 4」の「Child-indexed Pseudo-classes」に該当しますが、本記事では簡略化した「子要素インデックス」の表記を用います。 ↩
-
of S
のS
はセレクタリスト(selector list)です。,
(カンマ)区切りで複数のセレクタを指定することができます。 ↩ -
selector list argument of :nth-child and :nth-last-child CSS pseudo-classes | Can I use… ↩ ↩2