知っておくと便利なCSSのセレクタ! :has()疑似クラスを使用すると、子の数に基づいて親要素のスタイルを定義できる
Post on:2022年11月29日
CSSはどんどん便利になってますね!
:has()
もその一つで、指定した要素がある場合にのみスタイルを適用できます。その機能を利用して、子の数に基づいて親要素のスタイルを定義することができます。たとえば、子要素が3個以下の場合、ちょうど5個の場合、7~9個の場合などに親要素に異なるスタイルを設定するのが簡単です。
Style a parent element based on its number of children using CSS :has()
by Bramus
:has()
について詳しく知りたい人は、以前の記事をご覧ください。
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
CSS では疑似クラスの:nth-child
を使用して、兄弟の数に基づいて要素のスタイルを設定できます。しかし、子の数に基づいて親要素のスタイルを設定したい場合はどうすればよいでしょうか?
その答えは、CSSの:has()
です!
:has()を使用して、子の数に基づいて親要素のスタイルを設定
まずは、:has()
を使用した実際のコードをご覧ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/* 最大3個の子(0を除く3以下) */ ul:has(> :nth-child(-n+3):last-child) { outline: 1px solid red; } /* 最大3個の子(0を含む3以下) */ ul:not(:has(> :nth-child(3))) { outline: 1px solid red; } /* ちょうど5個の子 */ ul:has(> :nth-child(5):last-child) { outline: 1px solid blue; } /* 10個以上の子 */ ul:has(> :nth-child(10)) { outline: 1px solid green; } /* 7~9個の子(境界を含む) */ ul:has(> :nth-child(7)):has(> :nth-child(-n+9):last-child) { outline: 1px solid yellow; } |
:has()の仕組み
上記で構築された各セレクタのパターンは、次の通りです。
1 2 3 |
parent:has(> count-condition) { … } |
parent:has()
を使用することで、条件を満たす親要素を選択。:has()
に>
を渡すことで、親の直接の子を対象に。count-condition
(カウントの条件)は、実行したい選択の種類ごとに考える必要があります。数量クエリと同様に:nth-child()
を使用します。
:has()
は、しばしば親セレクタと呼ばれますが、実際にはそれ以上の機能を備えています。
最大x
個の子
:nth-child
に負の-n
を設定すると、最初のx
個の子を選択できます。そのうちの1つが最後の子である場合、親に最大x
個の子があるかどうかが分かります。
1 2 3 4 |
/* 最大3個の子(0を除く3以下) */ ul:has(> :nth-child(-n+3):last-child) { outline: 1px solid red; } |
このセレクタは、子を持たない親要素を除外します。テキストだけを含む要素はすべて一致するため、ほとんどの場合これは問題ありません。含めたい場合は、代わりに下記のセレクタを使用します。
1 2 3 4 |
/* 最大3個の子(0を含む3以下) */ ul:not(:has(> :nth-child(3))) { outline: 1px solid red; } |
ちょうどx
個の子
ちょうどx
個を選択するには、n
を設定せずに:nth-child
を使用します。その子が最後の子である場合、親にちょうどx
個の子があるかどうかが分かります。
1 2 3 4 |
/* ちょうど5個の子 */ ul:has(> :nth-child(5):last-child) { outline: 1px solid blue; } |
少なくともx
個の子
少なくともx
個の子がある親を選択するには、その中に子がx
個あるか分かれば判断できるので、:last-child
は必要ありません。
1 2 3 4 |
/* 10個以上の子 */ ul:has(> :nth-child(10)) { outline: 1px solid green; } |
x
~y
個の子
範囲の選択をするには、:has()
の条件式を2つ組み合わせます。1つ目の条件式にはx
個以上の子を持つすべての要素を選択し、2つ目の条件式にはy
個以上の子を持たない要素のみを選択することで、範囲を設定できます。これで2つの条件式に一致する要素のみが分かります。
1 2 3 4 |
/* 7~9個の子(境界を含む) */ ul:has(> :nth-child(7)):has(> :nth-child(-n+9):last-child) { outline: 1px solid yellow; } |
デモページ
実際の動作は、デモページをご覧ください。
:has()
を使用して、子の数に基づいて親要素のスタイルを設定しています。
- 最大3個の子: レッドのアウトライン
- ちょうど5個の子: ブルーのアウトライン
- 10個以上の子: グリーンのアウトライン
- 7~9個の子: イエローのアウトライン
See the Pen
Styling parent elements based on the number of children with CSS :has() by Bramus (@bramus)
on CodePen.
ブラウザのサポート
この記事で紹介したセレクタは、:has()
をサポートしているすべてのブラウザで機能します。
2022年11月現在、Firefoxではサポートされていません。Firefoxの実験的な機能で:has()
を有効にしても機能しません。
sponsors