フィルタリングにも対応できるnth-childの「of <selector>」を使ってストライプテーブルを作ってみよう

こんにちは、ユアサです。
以前業務内で活用してかなり便利だったので、今回はCSSセレクタの中でも便利なnth-childof <selector>を使って工夫したストライプテーブルを作成してみたいと思います。

of <selector>の使い方

nth-child(○番目 of 特定のセレクタ)と記述でき、特定のセレクタの条件に当てはまる子要素に対してスタイルを付与できるようになります。
例えば記述すると.contents:nth-child(1 of p)のようになり、この場合『クラス名「.contents」の要素内の子要素pタグの1番目』という意味合いになります。

nth-child()で事足りるんじゃない?

あえてof <selector>を使うことのメリットとして、通常のnth-child()に比べメンテナンス性が良い点にあります。
『クラス名「.contents」の要素内の子要素pタグの1番目』の条件でそれぞれCSSを書いてみました。

See the Pen nth-child_sample by felly (@felly00505) on CodePen.

See the Pen nth-child-of_tutorial by felly (@felly00505) on CodePen.

それぞれのコードを見比べてみます。

通常のnth-child()の方は、クラス名「.contents」の要素内にある子要素2番目がpタグである場合はセレクタの条件と合致しますが、仮にクラス名「.contents」の要素に子要素が追加された際には想定したスタイルが意図したところに反映されなくなる可能性が大きく、結局セレクタの条件も都度修正しなければいけません。

対してof <selector>を使用した方では、要素が増減しても『クラス名「.contents」の要素内の子要素pタグの1番目』にはスタイルが当たり続けるので、デザインを意識していれば前者よりもいちいちCSSを書き直す手間がなくなります。

ですがof <selector>の便利な仕様については他にもあるので、次のセクションでまとめていきます。

要素が動的に増減した場合にも対応できる

例えばストライプテーブルのような、規則性のあるデザインでスタイルが組まれたテーブルを作るとします。

『クラス名「.contents」内の偶数番目の要素が濃いグレーのストライプテーブル』とした時に、前述した2つのセレクタ指定の方法でそれぞれ以下のように実装できます。

See the Pen nth-child-normal_table by felly (@felly00505) on CodePen.

See the Pen nth-child-of_table by felly (@felly00505) on CodePen.

どちらもeven(偶数)の条件で、規則的に濃いグレーの背景色を当てることができています。
ここまでは良いのですが、このうちnth-child()の方では想定したストライプのスタイルでなくなってしまう場面があります。

See the Pen nth-child-normal_table01 by felly (@felly00505) on CodePen.

上記コードのように、nth-child()のストライプテーブルを動的にフィルタリングができるようにしてみました。いわゆる『動的に要素の増減ができる』状態になっています。

ナビゲーション内のカテゴリーの名前のボタンを押すと該当するカテゴリーの要素だけをフィルタリングしますが、フィルタリング後の表示を見てみるとストライプ表示のスタイルが当たっていたりなかったりします。
このため、フィルタリング後にCSSやらJSの記述を更に書き加えてどうにか表示をストライプ表示に戻してあげるという手間が発生する上、コードがややこしくなってしまいます。

これに対してof <selector>の方はどうでしょうか。

See the Pen nth-child-of_table01 by felly (@felly00505) on CodePen.

動作させてみると分かりますが、フィルタリング後でも想定したストライプ表示になっています。このように動的パーツとして作成した場合でも想定したスタイルが崩れない強みがありとても便利です。

おわりに

この仕様を知った時はちょっと感動しました。(毎回要素やプロパティを紹介する際には必ず言っている気がしますが)使い所がかなり多そうな上に、後々CSSを読んだ際にセレクタの条件を把握しやすいなと感じたので積極的に使っていきたいです。
最後まで読んでいただきありがとうございました。