:has() の条件は > で「直下」に絞る(入れ子の部品に反応させない)
.card:has(img) p は中のコメント欄のアバター画像にも反応し、コメント本文の段落まで塗ってしまう。.card:has(> img) > p と2か所に > を付けて、条件にする画像と当てる段落の両方を直下に限定する。
どんな時に使う?
「カードに画像があるときだけ本文の背景を変える」のように :has() で親の状態を切り替えるとき。カードの中にコメント・ユーザー情報・埋め込みなど別の部品が入ると、子孫セレクターのままでは意図しない要素が条件にも対象にもなる。
コード
css
/* NG: コメント欄のアバター <img> でも条件が成立し、コメント本文の <p> にも当たる */
.card:has(img) p {
background: #f4f6ff;
}
/* OK: カード直下に画像があるときだけ、カード直下の段落にだけ当てる */
.card:has(> img) > p {
background: #f4f6ff;
}- 1つ目の
>(:has()の中)は「どの画像を条件に数えるか」を決める。 - 2つ目の
>(:has()の外)は「どの段落にスタイルを当てるか」を決める。 - 同じ
>でも見ている場所が違うので、片方だけ付けても直らないことがある。
注意点・対応状況
:has()はすべての主要ブラウザで使える。- 構造がもっと深い場合は
>を重ねるより、.card__mediaのようにクラスで条件を指定した方が壊れにくい。部品の内側を切り離したいときは@scopeの下限も使える(@scope の「to (.scoped)」でコンポーネントのスタイル漏れを止める)。
出典
- @hayatastic(2026-11-04、比較デモとブログあり)