:has()
Matches an element that contains something matching the selector in brackets — the "parent selector".
Syntax
selector:has(relative) { … }Parameters
| Parameter | Type | Description |
|---|---|---|
| relative | selectors | A selector checked relative to the element: `img`, `> p`, `+ h3`, `input:checked`. |
Examples
A card with an image gets a different border:
<style>
.card { padding: 12px; border: 2px solid lightgray; margin-bottom: 8px; }
.card:has(img) { border-color: royalblue; }
</style>
<div class="card">Text only</div>
<div class="card"><img src="/media/photo-200x200.jpg" alt="" width="60"> With a photo</div>The label is highlighted when its checkbox is checked:
<style>
label:has(input:checked) { background: palegreen; }
</style>
<label><input type="checkbox"> I agree</label>Notes
:has() works in all current browsers (since 2023). It is not allowed inside another :has(). Keep the argument simple — a very broad :has() on body makes the browser recheck a lot on every change.
See also
Related recipes
In the tutorial
- Modern selectors — The :is(), :where(), :not() with a list and :has() selectors — how to shorten long selectors and pick a parent by its content.