:has() selector
:has() は CSS の擬似クラス関数で、引数として渡される相対セレクターのいずれかが、その要素から辿ってアンカーとして少なくとも一つの要素と一致する場合に、その要素を表します。この擬似クラスは、相対セレクターリストを引数として取ることで、参照している要素に関して親要素や前の兄弟要素を選択する方法を提供します。
css
/* h1 見出し要素の直後に段落要素がある場合、 その h1 要素に対してスタイルを適用します */ h1:has(+ p) { margin-bottom: 0; }
:has() 擬似クラスは :is() や :not() と同様に、引数の中で最も大きい詳細度が :has() の詳細度として与えられます。
対応ブラウザ
| 機能 | デスクトップ | モバイル | ||||
|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Safari | Chrome Android | Safari iOS | |
| 105 | 105 | 121 | 15.4 | 105 | 15.4 | |
基本構文
CSS
/* Style labels with checked checkbox inputs */
label:has(input[type="checkbox"]:checked) {
background: #e0f2fe;
font-weight: bold;
}
figure:has(img) {
border: 2px solid #ddd;
padding: 8px;
}
h2:has(+ p) {
margin-bottom: 4px;
} ライブデモ
実務での使いどころ
-
フォームのバリデーション表示
エラーがある input を持つ .form-group 全体をハイライト。JS不要で包括的なスタイル変更が可能。
-
チェックボックス連動UI
チェック済みの input を持つ親カードの背景・ボーダーを変える。カートやタスクリストで有効。
-
メディア有無によるレイアウト分岐
img がある .card と ない .card で異なるレイアウト。
-
セクション見出しの調整
直後に p が続く h2 だけ margin-bottom を縮める。
注意点
- パフォーマンス — 複雑なセレクターはレイアウト再計算コストが増える。
- Firefox 121未満は動作しない。
- IE 完全非対応。
フォールバック戦略
CSS
@supports not selector(:has(*)) {
.js-fallback { display: block; }
}
@supports selector(:has(*)) {
label:has(input:checked) {
background: #e0f2fe;
}
} アクセシビリティ
- 視覚的なスタイル変更はスクリーンリーダーに伝わらない。aria-checked などを必ず併用。
- フォームのエラー表示は role="alert" でテキストとしても提供する。
- 色のみで状態を伝えず、色+テキストを組み合わせる。