🔢

CSSの:has()で要素の個数に応じてスタイルを適用する

2022/12/06に公開

記事一覧や商品一覧など、要素の個数によって CSS を変えたいときに使えるテクニックです。目新しいテクニックではないですが、:has() セレクタで書き直したものになります。

要素の個数が N 個以上

N 番目の要素 :nth-child(N) を直下 > に持つ :has()<ul> 要素があれば、N 個以上と判定できます。

꞉has()を使った手法
ul:has(> :nth-child(N)) li { ... }

後ろから数えて N 番目以降 :nth-last-child(n+N) と、それ以降 ~ li で残りの要素を選択できるので、合わせると N 個以上と判定できます。

従来の手法
ul > :nth-last-child(n+N),
ul > :nth-last-child(n+N) ~ li { ... }

さらに条件を追加することもでき、要素の個数が N 個以上のときの奇数番目を選択するには次のようにします。

꞉has()を使った手法
ul:has(> :nth-child(N)) :nth-child(2n+1) { ... }
従来の手法
ul > :nth-last-child(n+N),
ul > :nth-last-child(n+N) ~ :nth-child(2n+1) { ... }

要素の個数が N 個以下

-n+N 番目の要素 :nth-child(-n+N) かつ、その要素が最後:last-child であるような要素を直下 > に持つ :has()<ul> 要素があれば、N 個以下と判定できます。

꞉has()を使った手法
ul:has(> :nth-child(-n+N):last-child) li { ... }

後ろから数えて N 番目以前 :nth-last-child(-n+N) かつ、その要素が最初 :first-child であるような要素と、それ以降 ~ li で残りの要素を選択できるので、合わせると N 個以下と判定できます。

従来の手法
ul > :first-child:nth-last-child(-n+N),
ul > :first-child:nth-last-child(-n+N) ~ li { ... }

要素の個数が N 個

N 番目の要素 :nth-child(N) かつ、その要素が最後:last-child であるような要素を直下 > に持つ :has()<ul> 要素があれば、N 個と判定できます。

꞉has()を使った手法
ul:has(> :nth-child(N):last-child) li { ... }

後ろから数えて N 番目 :nth-last-child(N) かつ、その要素が最初 :first-child であるような要素と、それ以降 ~ li で残りの要素を選択できるので、合わせると N 個と判定できます。

従来の手法
ul > :first-child:nth-last-child(N),
ul > :first-child:nth-last-child(N) ~ li { ... }

また、要素の個数が偶数個の場合は以下のようにします。

꞉has()を使った手法
ul:has(> :nth-child(2n):last-child) li { ... }
従来の手法
ul > :first-child:nth-last-child(2n),
ul > :first-child:nth-last-child(2n) ~ li { ... }

要素の個数が M 個以上 N 個以下

M 番目の要素 :nth-child(M) と、-n+N 番目の要素 :nth-child(-n+N) でそれが最後 :last-child となるような要素の両方を持つ :has()<ul> 要素があれば、M 個以上 N 個以下と判定できます。

꞉has()を使った手法
ul:has(> :nth-child(M)):has(> :nth-child(-n+N):last-child) li { ... }

後ろから数えて n+M 番目 :nth-last-child(n+M) かつ、後ろから数えて -n+N 番目 :nth-last-child(-n+N) かつ、その要素が最初 :first-child であるような要素と、それ以降 ~ li で残りの要素を選択できるので、合わせると M 個以上 N 個以下と判定できます。

従来の手法
ul > li:nth-last-child(n+M):nth-last-child(-n+N):first-child,
ul > li:nth-last-child(n+M):nth-last-child(-n+N):first-child ~ li { ... }

Discussion