「子や後続の要素が条件を満たす親・前の要素」を選択できる擬似クラスです。長年不可能だった『親セレクタ』を実現し、JavaScriptなしで子の状態に応じた親のスタイリングができます。
:has(<relative-selector-list>)/* 画像を含むカードだけレイアウトを変える */
.card:has(img) {
display: grid;
grid-template-columns: 120px 1fr;
}画像を含むカードにだけグリッドレイアウトを適用
/* 入力が無効な時にフィールド全体を強調 */
.field:has(input:invalid) {
border-color: red;
background: #fff5f5;
}子のinputの検証状態に応じて親フィールドを装飾
/* チェックされたら次の要素ではなく“前”のラベルを変える */
label:has(+ input:checked) {
font-weight: bold;
color: #2563eb;
}直後の兄弟がチェック済みのラベルを強調(前方の要素を選択)
「〜を含む」だけでなく:has(> img)で直下限定、:has(+ .next)で兄弟条件も書けます。フォームの状態連動UI(:has(:checked)や:has(:focus-visible))はJavaScript削減の定番パターンです。
:has()の中に:has()はネストできません。また詳細度は引数のセレクタで決まるため、:has(#id)のような指定は詳細度が跳ね上がり上書きしにくくなります。
AIは学習時期によって「:has()は未対応ブラウザが多いのでJavaScriptで実装すべき」と古い提案をしがちですが、2023年12月に全主要ブラウザ対応済み(Baseline)です。逆にAIが生成した:has()が意図通り動かない場合、:has()内のネスト(:has(:has())は不可)や、擬似要素(::before等)を引数に書いている(無効)ケースが典型です。
チェックボックスがONのとき、その親のカード全体の背景色を変えたい。JavaScriptを使わず:has()で実装して
input:invalidのときにラベルの色を赤にしたい。ラベルがinputの前にあるHTML構造のまま:has()で書いて
このjQueryの親要素操作コードを、:has()を使ったCSSだけの実装に置き換えられるか検討して
そのままAIチャットに貼り付けて使える依頼文の例です。ページ上部の「AI用にコピー」でこのページ全体をコンテキストとして渡せます。