:has()
The functional :has() CSS pseudo-class represents an element if any of the relative selectors that are passed as an argument match at least one element when anchored against this element. This pseudo-class presents a way of selecting a parent element or a previous sibling element with respect to a reference element by taking a relative selector list as an argument.
css
/* Selects an h1 heading with a paragraph element that immediately follows the h1 and applies the style to h1 */ h1:has(+ p) { margin-bottom: 0; }
The :has() pseudo-class takes on the specificity of the most specific selector in its arguments the same way as :is() and :not() do.
Browser support
| Feature | Desktop | Mobile | ||||
|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Safari | Chrome Android | Safari iOS | |
| 105 | 105 | 121 | 15.4 | 105 | 15.4 | |
Syntax
/* 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;
} Live demo
Use cases
-
Browser-native behavior
Use :has() to rely on the platform for behavior that would otherwise require extra code or CSS complexity.
-
Progressive enhancement
Enhance the experience where support exists while keeping a solid baseline elsewhere.
Cautions
- Check browser support and actual product need before adding a new platform feature widely.
- Keep feature usage understandable so future contributors know why it was chosen.
Accessibility
- New platform features should still preserve readable defaults and robust interaction patterns.
- Verify that enhancement paths do not leave unsupported environments with a broken experience.