朗報! CSSの:has()疑似クラスがすべてのブラウザにサポートされました、:has()疑似クラスの便利な使い方のまとめ

CSSの:has()疑似クラスは便利そうだけどブラウザのサポートがまだ、と見送っていた人に朗報です。12/19にリリースされたFirefox 121(リリース情報)でサポートされ、これで:has()疑似クラスがすべてのブラウザにサポートされました。

そんな:has()疑似クラスの便利な使い方を紹介します。

CSSの:has()疑似クラスの便利な使い方のまとめ

:has()疑似クラスのサポートブラウザ

Firefoxにサポートされたことで、:has()疑似クラスがすべてのブラウザにサポートされました。

:has()疑似クラスのサポート状況

:has()疑似クラスのサポート状況
※まだFirefox 121の分がアップデートされていないようです。

Chrome, Edgeは105から、Safariは15.4からサポートされているので、来年は:has()疑似クラスを使用する機会も増えるでしょう。

また、12/20にアップデートされたTailwind CSS v3.4(リリース情報)でも:has()疑似クラスがサポートされました。

:has()疑似クラスの基礎知識

CSSの:has()疑似クラスとは、指定した要素がある場合にのみスタイルを適用できるCSSの新機能です。

今までのCSSでは、要素の存在のあり・なしによって特定の親や要素にスタイルを設定することは不可能でした。あり用となし用のクラスを作成し、必要なバリエーションに応じて切り替える必要がありました。
たとえば、こんな感じです。

カードのコンポーネント

上: 画像があるカード、下: 画像がないカード

カードコンポーネントには、2つのバリエーションがあります。

  1. 画像あり
  2. 画像なし

今までのCSSでは、下記のように2つのクラスを作成して実装します。

画像なしにはFlexboxが必要ないため、なし用とあり用の2つのバリエーションのクラスを作成しました。このような場合にバリエーションのクラスを作成しないで、CSSで条件式のように定義できるとしたら、どう思いますか。

ここで、CSSの:has()の出番です!
:has()を使用すると、.card要素の中に.card__imageがあるかどうかをチェックできます。

たとえば、カードに画像があるかどうかをチェックし、ある場合にはFlexboxで配置できます。

さらに詳しく知りたい人は、下記をご覧ください。

:has()疑似クラスの基本的な使い方

:has()疑似クラスを使用すると、子の数に基づいて親要素のスタイルを設定できます。

実際の動作は、デモページをご覧ください。
:has()を使用して、子の数に基づいて親要素のスタイルを設定しています。

  • 最大3個の子: レッドのアウトライン
  • ちょうど5個の子: ブルーのアウトライン
  • 10個以上の子: グリーンのアウトライン
  • 7~9個の子: イエローのアウトライン

See the Pen
Styling parent elements based on the number of children with CSS :has()
by coliss (@coliss)
on CodePen.

さらに詳しく知りたい人は、下記をご覧ください。

:has()疑似クラスの便利な使い方

:has()疑似クラスを使用するとさまざまなセレクタを条件式のように記述できます。

では:has()疑似クラスを実際にどのように使用するのか、いくつか例を見てみましょう。

カードの実装

まずはシンプルなカードのデモを見てみましょう。
カードにはタイトルやサブタイトル、画像などのメディアなど、あらゆる情報を配置できます。カードの基本的なHTMLは下記の通りです。

実際の動作は、デモをご覧ください。

See the Pen
Basic Card
by coliss (@coliss)
on CodePen.

カードに画像を配置したいときはどうしますか?
カードでは2つのカラムを使用できます。今まではcard--with-mediacard--two-columnsのようなクラスを作成していたかもしれません。このようなクラス名は、思いつくのが難しいだけでなく、それをずっと覚えておくのも難しいものです。

:has()疑似クラスを使用すれば、カードが何らかのメディアを持っていることを検出して、適切なスタイルを適用できます。修飾子(Modifier)のクラス名は必要ありません。

実際の動作は、デモをご覧ください。

See the Pen
Card with Media
by coliss (@coliss)
on CodePen.

これだけではありません、もっとクリエイティブになれるはずです。特集コンテンツを表示するカードは、レイアウト内でどのように適応させますか? 下記のCSSは、特集を表示するカードをレイアウトの幅いっぱいに表示し、グリッドの最初に配置します。

実際の動作は、デモをご覧ください。

See the Pen
:has Media Card Layouts
by coliss (@coliss)
on CodePen.

さらに、バナーがある特集カードで注目を集めるためにアニメーションさせてみます。

アニメーションは6秒間隔で動かしてみます。

実際の動作は、デモをご覧ください。

See the Pen
:has Wiggle Card
by coliss (@coliss)
on CodePen.

:has()疑似クラスには多くの可能性があります!

フォームの実装

フォームはCSSでスタイルするのが難しいことで知られています。たとえば、入力欄とそのラベルのスタイルです。入力が有効であることを示すにはどうすればよいでしょうか?

:has()疑似クラスを使用すると、これが非常に簡単になります。:valid:invalidなど、関連するフォームの疑似クラスをフックにできます。

実際の動作は、デモをご覧ください。
有効な値と無効な値を入力し、フォーカスをオンまたはオフにしてみてください。

See the Pen
:has some <input>
by coliss (@coliss)
on CodePen.

さらに、:has()疑似クラスを使用して、エラーメッセージを表示・非表示することもできます。Emailのフィールドグループを使用して、エラーメッセージを追加してみます。

デフォルトでは、エラーメッセージを非表示にします。

そしてフィールドが:invalidになり、かつフォーカスされていない場合、追加のクラス名を必要とせずにメッセージを表示できます。

実際の動作は、デモをご覧ください。

See the Pen
This form shows and hides its error messages
by coliss (@coliss)
on CodePen.

さらにフォームにセンスのいいアクションを加えてみます。無効な値を入力すると、フォームグループを揺らします(※ユーザーがモーション設定していない場合)。こういったマイクロインタラクションも:has()疑似クラスを使用すると、簡単に実装できます。

See the Pen
This <input> :has an error message
by coliss (@coliss)
on CodePen.

コンテンツの実装

コンテンツの実装は:has()疑似クラスの基本的な使い方で触れましたが、ドキュメントフローで:has()疑似クラスを使用するにはどうすればよいでしょうか?

たとえば、テキスト間にある画像のスタイルです。

この例では、画像がいくつ含まれています。画像にfigcaptionがない場合はコンテンツ内にフロートされ、figcaptionがある場合は全幅を占め、追加のマージンを与えます。
実際の動作は、デモをご覧ください。

See the Pen
An article that :has <figure>
by coliss (@coliss)
on CodePen.

さらに詳しく知りたい人は、下記をご覧ください。

sponsors

top of page

©2024 coliss