cssの:has()疑似クラスの使い方

2023年12月、cssの:has()疑似クラスがすべてのブラウザでサポートされました。
:has()の使い方を改めて確認してみようと思います。

:has()とは

CSSの :has() とは、特定の子要素や子孫要素を持つ要素を選択するために使用されます。
これは「親要素が特定の条件を満たす子要素を持っている場合に、その親要素をスタイルする」ということです。
別の言い方をすると、「もし中に〇〇がある場合…」という条件を表します。

まずは基本的な使い方

下記の例は.contentsの子要素に「.contents-img」がある場合のみスタイルを適用することができます。
この例であれば、画像があれば背景をグレーにします。コンテンツ1は画像があるので背景はグレーになり、コンテンツ2は画像がないので変化はありません。

.contents:has(.contents-img) {
  background-color: #ddd;
}

See the Pen has_01 by naoto saito (@code_ns) on CodePen.

下記のように「.contents-img」のクラス名ではなくimgタグがある場合の時という指定もできます。

.contents:has(img) {
  background-color: #ddd;
}

See the Pen has_02 by naoto saito (@code_ns) on CodePen.

:hoverや:focusなどと組み合わせる

中の要素がhoverした時やinputにfocusした時にのみスタイルを適用することができます。
下記はボタンにhoverした時、inputにfocusした時のみ「.contents」のスタイルが変わります。

.contents:has( button:hover ) {
  box-shadow: 0px 2px 47px -14px #777777;
}

.contents:has( input:focus ) {
  outline: 2px solid #00f;
}

See the Pen has_04 by naoto saito (@code_ns) on CodePen.

:notとの組み合わせ

否定擬似クラスの「:not()」と組み合わせることができます。
下記の例は、画像がない場合背景がグレーになります。

.contents:not(:has(.contents-img)) {
  background-color: #ddd;
}

See the Pen has_01 by naoto saito (@code_ns) on CodePen.

直下セレクタとの組み合わせ

下記のように直下セレクタと組み合わせることができます。

.contents:has( > .contents-text ) {
  background-color: #ddd;
}

See the Pen has_06 by naoto saito (@code_ns) on CodePen.

独自データ属性との組み合わせ

下記のように独自データ属性と組み合わせることができます。

.contents:has( .contents-title[data-a="hoge"] ) {
  background-color: #ddd;
}

See the Pen has_06 by naoto saito (@code_ns) on CodePen.

いかがでしょうか?
cssの:has()疑似クラスの使い方を確認しました。意外と柔軟に色々なことと組み合わせができますね!
今までjsを使わないと選択できなかった親要素が、今回のhas()を使うことで対応できるので今後どんどん利用しようと思います。