on:2022年4月21日sponsors先日の記事で:has()疑似クラスがSafariでサポートされ、こんなことができるというのを紹介しましたが、さらに:has()疑似クラスを掘り下げ、Webサイトやアプリでの便利な使い方を紹介します。:has()疑似クラスは、指定した要素がある場合にのみスタイルを適用できるCSSの新機能で、これからのWeb制作に活躍するかなり便利な機能です。いう機能を待ち望んでいた人も多いと思います。カードに画像がある場合、ナビゲーションに子メニューがある場合、ラッパーがある場合など、複雑なCSSが必要だったものやJavaScriptが必要だったものが簡単でシンプルなCSSで実装できます。Shadeed下記は各ポイントを意訳したものです。※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。flex;を追加する、という感じです。今までは不可能でしたが、CSSに新しいセレクタ:has()が登場し、特定の要素が親の中に存在するかなど、さまざまな要素を選択できるようになります。この記事では、:has()で解決される問題、それがどのように機能するか、その実装方法とどこでどのように使用できるか、そして最も重要なこととして、今日から使用できる方法について解説します。:has()を使用すると、こんなことができるようになります今までのCSSでは、要素の存在のあり・なしによって特定の親や要素にスタイルを設定することは不可能でした。あり用となし用のクラスを作成し、必要なバリエーションに応じて切り替える必要がありました。画像がないカードカードコンポーネントには、2つのバリエーションがあります。画像あり画像なし今までのCSSでは、下記のように2つのクラスを作成して実装します。--></div></div>画像なしにはFlexboxが必要ないため、なし用とあり用の2つのバリエーションのクラスを作成しました。このような場合にバリエーションのクラスを作成しないで、CSSで条件式のように定義できるとしたら、どう思いますか。ここで、CSSの:has()の出番です!:has()を使用すると、.card要素の中に.card__imageがあるかどうかをチェックできます。カードに画像があるかどうかをチェックし、ある場合にはFlexboxで配置できます。center;}:has()疑似クラスとはCSSの仕様によると、:has()疑似クラスは親要素に少なくとも1つの要素が含まれているかどうか、あるいはフォーカスが当たっているかどうかなど、1つの条件が含まれているかどうかをチェックできます。前述のCSSをもう一度確認してみましょう。}このCSSは、.cardの親要素に.card__imageの子要素が含まれているかどうかをチェックします。このCSSを言葉に置き換えてみます。画像が含まれているカードにのみ、スタイルを適用します。これはすごいことだと思いませんか!CSSでロジックを扱えるようになりました。CSSでこんなことができるとは、なんて素晴らしい時代になったのでしょう。:has()疑似クラスは親だけではありません:has()疑似クラスは、親が子を含んでいるかどうかだけでなく、たとえば、ある要素の後に<p>が続いているかどうかもチェックできます。}このCSSは、<h2>要素の直後に<p>要素が続くかどうかをチェックします。form要素に使用してフォーカスされたinput要素があるかどうかをチェックする、といった使い方もできます。フォーム内にフォーカスされた入力欄がある場合、スタイルを適用します。フォーム内にフォーカスされた入力欄がある場合、スタイルを適用します。15.4でサポートされました。Canaryでのみ動作します。Chromeは次期101のflagsで使用できる予定で、すべてのブラウザにサポートされる日が近づいてきました。Operaでもサポートされました。:has()疑似クラスのサポート状況:has()疑似クラスはエンハンスメントとして使用できるかはい、CSSの@supportsルールで使用できます。*/}【訳者注】:has()疑似クラスをすぐに使用したい場合は、ポリフィルもリリースされています。Pseudo(IEもサポート):has()疑似クラスの使用例:has()疑似クラスを使用した便利な使い方を紹介します。Webサイトやアプリでよく使用されるコンポーネントやレイアウトに大活躍します。セクションのヘッダセクションのヘッダを実装する時、タイトルだけ、タイトルとリンク、の2つのバリエーションを用意することがあります。デモページリンクの有無によって、スタイルを変えます。a)で、直接の子リンクがあるかどうかをチェックします。1最初のカードの例に少し話を戻しましょう。画像ありと画像なしの2つのバリエーションがあります。デモページまずは、前述のCSSです。画像ありの場合にスタイルを適用します。center;}:not()を使用すると画像なしもチェックできます。画像なしの場合は上にボーダーを適用します。#7c93e9;}:has()疑似クラスを使用しないでこれを実装すると、下記のように2つのクラスが必要になります。2カードの違う使用例を見てましょう。このカードでは、下部にアクションがない場合とアクションがある場合の2つのバリエーションがあります。flex;を有効にしたいと思います(HTMLは気にしないでください、単にデモ用です)。space-between;}:has()疑似クラスを使用しない場合は、下記の通りです。3カードに画像があるかないかでborder-radiusを変更する必要があったことはありませんか。:has()疑似クラスの完璧な使用例です。画像を取り除いてしまうだけと、残された上部の角丸がなくなってしまい、奇妙に見えます。画像なしの場合、左上と右上に角丸を追加します。画像なしの場合、左上と右上に角丸を追加します。12px;}:has()疑似クラスを使用すると、画像なしの場合の角丸も簡単に実装できます。デモページ:has()疑似クラスを使用しない場合は、下記の通りです。12px;}フィルタリングコンポーネントフィルタリングは、複数のオプションを持つコンポーネントです。いずれもチェックされていない場合は、リセットボタンはありません。少なくとも1つがチェックされている場合は、リセットボタンを表示する必要があります。デモページ:has()疑似クラスを使用すると、簡単に実装できます。block;}これは:has()疑似クラスを使用しない場合は、CSSで実装はできません。:has()疑似クラスのサポートが良好になったら、JavaScriptを捨てる予定の一つです。以前の回答や選択に基づいて、フォームの項目を表示する場合があります。ユーザーがセレクトメニューから「その他」を選択した場合に、「その他」フィールドを表示する必要があります。デモページ:has()疑似クラスを使用すると、セレクトメニューで「その他」が選択されているかどうかをチェックし、それに基づいて「その他」フィールドを表示できます。block;}これも素晴らしいことだと思いませんか?セレクトメニューとフィールドが.box親要素内にあれば、HTMLソースの順番を気にする必要はありません。サブメニュー付きのナビゲーションホバーやフォーカスで表示されるサブメニューを備えたナビゲーションがあります。デモページここでやりたいことは、サブメニューがあるかないかで矢印を表示・非表示にすることです。:has()疑似クラスを使用すれば、簡単にできます。<li>に<ul>が含まれているかどうかをチェックし、ある場合に矢印アイコンを表示します。*/}:has()疑似クラスを使用しない場合は、おそらくサブメニューを備えた<li>へのクラスで実装します。*/}ヘッダのラッパーヘッダコンポーネントを実装する際、ヘッダをページの全幅にするか、ラッパー内に含めるか迷うことがあります。デモページどちらにせよ、ヘッダ内の要素を配置するためにFlexboxを使用する必要があります。.wrapperがある場合は、それにスタイルを適用します。ない場合は、.site-header要素に直接適用します。1rem;}アラートの強調表示ユーザーが知っておかなければならない重要なアラートが存在する場合があります。その場合、通常のアラートだけでは十分でない可能性があります。そのような場合、たとえば、header要素に赤いボーダーと薄赤色の背景色を追加して表示します。デモページ:has()疑似クラスを使用すれば、.main要素にアラートがあるかどうかをチェックし、ある場合にはヘッダにスタイルを追加できます。#fff4f4;}カラーテーマの変更:has()疑似クラスを使用して、Webページの配色を変更できます。CSS変数を使用して作成された複数のテーマがある場合、セレクトメニューで変更できます。#f1dceb;}デモページセレクトメニューからカラーを選択すると、CSSでは次のようなことが起こります。選択されたオプションに基づいて、CSSの変数が変更されます。#f1dceb;}デモページ生成されたHTMLのスタイル場合によっては、HTMLを変更できないことがあります。コンテンツ管理システム(CMS)が予期せぬ方法で要素を生成するかもしれませんし、著者が動画などを埋め込むかもしれません。本文内で、段落が続いていない<h3>を選択し、その下のスペースを広げます。1.5rem;}あるいは、<h3>に続いている<iframe>を選択して実行する必要があるかもしれません。このような場合は:has()疑似クラスでないと対応できません。*/}アイコン付きのボタンデフォルトのボタンスタイルがあり、さらにアイコンがある場合があります。アイコン付きはFlexboxを使用して中央揃えにします。デモページ:has()疑似クラスを使用して、アイコンがある場合のスタイルを設定します。center;}複数のボタンデザインシステムにおいて、アクションボタンを複数個用意することはよくあります。2つ以上のボタンがある場合、最後のボタンは反対側の端に表示されます。デモページ数量クエリを使用して実現できます。auto;で右に押し出すように配置します。auto;}情報モジュールこの例は、Pinterestのデザインシステムから得たものです。入力にエラーがあるときは、見出しを変えてその旨を表示します。:has()疑似クラスを使用して、エラーがある場合のスタイルを設定します。Gridでは、minmax()関数を使用して、真にレスポンシブで自動サイズのグリッドアイテムを作成できます。これだけでは不十分な場合があります。アイテム数に応じてグリッドを変更したいと思います。1rem;}アイテムが5つの場合、最後のアイテムは新しい行に折り返されます。.wrapperに5つ以上のアイテムが含まれているかどうかをチェックすることで、これを実装できます。これはさきほどの数量クエリを使用しています。120px;}画像とキャプションキャプションなしの画像とキャプションありの画像があります。この例では、HTMLの<figure>で実装されています。<figcaption>があれば、スタイルは少し異なるはずです。3px;}終わりにみなさんが:has()疑似クラスを使用して何を実装するのか、今から楽しみです。この記事で紹介した使用例は、ほんの一部に過ぎません。この先、たくさんの便利な使用方法が見つかると確信しています。今がCSSを学ぶのに一番いい時期だと思います。次に何が起こるか、とても楽しみです。ここまで、お読みいただきありがとうございました。Selector”この記事があなたのお役に立てれば幸いです。コメントや提案があれば、@shadeed9までお願いします。