※この記事はに最終更新されました。
:has()の使い方を徹底解説!
知っておきたい最新モダンCSS
モダンCSSとは?
近年ではCSSの進化が著しく、さまざまな新機能が実装されてきました。
そういったCSSの機能を総称して、「モダンCSS」と呼びます。
どこからが”モダン”にあたるのか、はっきりとした定義はないようなので、
「 ここ数年で新しく実装されたCSSの機能 」
を一括りにモダンCSSと捉えて問題ないかと思います。
本記事では、その中でも汎用性の高い機能とされる「 :has() 」について紹介していきたいと思います。
モダンCSSを知らない方、または、知っているけどまだ使っていない方の参考になれば幸いです。
モダンCSSの機能 「 :has() 」
:has()は、「State of CSS 2023」の、前年比で使用実績がもっとも増えた機能として表彰されています。
どんな機能かというと、特定の要素の 親要素 と 兄要素 を選択できます。
従来のCSSでは、特定の要素を基点としたときに、直後に位置している要素(子要素、弟要素)のみしか選択できなかったため、直前に位置している要素(親要素、兄要素)を選択するにはJavascriptが必要でした。
1.使い方
<div class=”box”>
<h1 class=”title”>タイトル</h1>
<img src=”image.jpg” class=”image”>
</div>
2.使用例
:has()は、特定の子要素/弟要素の有無によって、デザインレイアウトを分けたいケースに便利です。
使用例をいくつかご紹介します。
① サムネイル画像の有無で変わるカードレイアウト
See the Pen
:has() サムネイル画像の有無で変わるカードレイアウト by e-coding (@e-coding)
on CodePen.
② アイコンの有無で変わるボタンデザイン
See the Pen
:has() アイコンの有無で変わるボタンデザイン by e-coding (@e-coding)
on CodePen.
③ サブメニューの有無で変わるナビゲーション
See the Pen
:has() サブメニューの有無で変わるナビゲーション by e-coding (@e-coding)
on CodePen.
3.注意点
注意点① 複雑なセレクタはコードの保守性を下げる可能性あり
:has()を使うことで、例えば以下のように複雑なセレクタも作成できます。
ただ、あまりに複雑なセレクタを作成すると、後からHTMLコードを変更した際に破綻する可能性もあります。
コードにある程度柔軟性を持たせたい場合や、:has()の使い方をまだ十分に理解していない段階では、シンプルなセレクタのみを作った方が安全でしょう。
複数のセレクタ
.titleと.imageを持っている親要素
(例1).box:has(.title,.image){ ~ }
(例2).box:has(.title):has(.image){ ~ }
:not()との組み合わせ
.imageを持っていない親要素
(例).box:not(has(.image)){ ~ }
特定の要素を持つ親要素内のセレクタ
.titleを持つ.box内の.image
(例).box:has(.title) .image{ ~ }
数量クエリとの組み合わせ
.imageを2つ以上持っている親要素
(例).box:has(.image:nth-last-child(n+2)) { ~ }
注意点② 詳細度
:has()の詳細度は、少し特異のため注意が必要です。
詳細度について詳しい説明は割愛しますが、簡単に言いますと、ある要素に対し複数のCSS宣言が競合した際に、どのプロパティ値を適用させるかを決める尺度になります。
詳細度が高いCSSほど優先的にプロパティ値が適用されます。
:has()では、:has()内部のセレクタも詳細度に追加されます。
下の例を見てください。
.box:has(p) と .box の両方からbackground-colorを指定していますが、 .box:has(p) の方が適用されていることが分かります。
.box:has(p) には、:has()の中のpタグが詳細度に加えられるため、 .box よりも詳細度が高くなり、優先的にプロパティ値が適用されます。
See the Pen
:has()の詳細度 by e-coding (@e-coding)
on CodePen.
4. 各ブラウザのサポート状況
:has()のサポート状況ですが、
2024年11月現在は、Chrome・Edge・Safari・Operaでサポートされています。
まとめ
いかがでしたでしょうか?
:has()のように、近年ではJavascriptに代わるCSSの機能が増えています。
CSSはブラウザのレンダリングエンジンによって最適化されており、アニメーションやスタイル変更などの処理がJavaScriptよりも高速かつスムーズに実行されます。
また、コードに関してもより簡易的です。
Javascriptの代わりにモダンCSSの機能を取り入れることで、パフォーマンスと保守性の両方を高めることができますので、おすすめです。