CSSに新しく加わった強力なセレクター:has()
。この関数型疑似クラスは、親要素が特定の子や兄弟要素を持っているかを条件にスタイルを変えることができ、これまでJavaScript頼みだった「条件付きのスタイル変更」をCSS単体で実現できるようになりました。今回は、その具体的な使い方と応用パターンを一挙にご紹介いたします。
【例1】特定の子孫要素を持つ場合に装飾を変える
親要素が<em>
や<a>
などの要素を含んでいるときだけ、背景色を変更することができます。
.notice:has(em),
.notice:has(a) {
background-color: #fff3cd;
padding: 10px;
border-left: 4px solid #ffcc00;
}
<div class="notice">
<em>重要</em>なお知らせです。
</div>
【例2】複数の要素を含む場合のみ(AND条件)で装飾
:has()
を連結することで、より厳密な条件も設定可能です。
.alert-box:has(strong):has(button) {
border: 2px dashed #c00;
background: #ffe6e6;
}
<div class="alert-box">
<strong>警告!</strong>
<button>閉じる</button>
</div>
【例3】直下の子要素にだけ限定する
>
を使えば、「孫要素」は無視して、直下の子要素だけを対象にできます。
.card:has(> img) {
border-top: 5px solid #007bff;
}
<div class="card">
<img src="header.jpg" alt="サムネイル">
<div class="text">コンテンツ</div>
</div>
【例4】次に来る兄弟要素の存在でスタイル変更
+
結合子で、後続の兄弟要素を条件にできます。
.label:has(+ .input-field) {
font-weight: bold;
color: #00796b;
}
<label class="label">名前</label>
<input class="input-field" type="text">
【例5】子孫に特定の要素が「含まれていない」場合
:not(:has(...))
で、特定要素の欠如を検出できます。
.comment:not(:has(img)) {
padding-left: 20px;
background-color: #f9f9f9;
}
<div class="comment">テキストのみのコメント</div>
【例6】リンクがホバーされた時に周囲も反応させる
:has(a:hover)
によって、間接的に画像などにもスタイルを波及させられます。
.panel:has(a:hover) ~ img {
outline: 2px dashed #cc0000;
}
<div class="panel">
<a href="#">画像を見る</a>
</div>
<img src="photo.jpg" alt="表示される画像">
【例7】チェックボックスの状態で外枠を変化
チェックされたときに外枠が赤くなるようなUIもCSSだけで可能です。
.options:has(input[type="checkbox"]:checked) {
border: 2px solid crimson;
}
<div class="options">
<input type="checkbox" id="agree">
<label for="agree">同意します</label>
</div>
【例8】子要素の「数」で条件を分岐
要素の数によってスタイルを変更できるユニークな使い方もあります。
.gallery:has(> :last-child:nth-child(4)) {
background-color: #e0f7fa;
}
<div class="gallery">
<img src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
<img src="4.jpg">
</div>
【例9】カードレイアウトで画像の有無に応じて構造変更
.profile {
display: flex;
flex-direction: column;
}
.profile:has(img) {
flex-direction: row;
align-items: center;
}
.profile img {
margin-right: 15px;
}
<div class="profile">
<img src="user.jpg" alt="写真">
<p>ユーザー情報です。</p>
</div>
【対応ブラウザー一覧】
:has()
は比較的新しいセレクターのため、全ブラウザーで使用できるわけではありません。現時点(2025年時点)では、以下のブラウザーで安定的にサポートされています。

- Google Chrome:105以降 ✅
- Microsoft Edge:105以降 ✅
- Safari:15.4以降 ✅
- Opera:91以降 ✅
- Firefox: ❌ 非対応(2025年5月現在)
対応状況の詳細は以下をご参照ください:
https://caniuse.com/css-has
【参考リンク】
【まとめ】CSSの可能性を広げる:has()の実力
:has()
は単なる新機能ではなく、CSS設計のパラダイムを変える重要な一歩です。構造に基づく動的な表現が、JSに頼らず実現できるようになり、保守性やパフォーマンスにも好影響を与えます。ブラウザ対応の範囲を確認しつつ、今から積極的に取り入れていきましょう。