intermediate
:has selector
Use relational selectors for parent-state styling, form states, feature replacement, and selector cost awareness.
`:has()` is a relational pseudo-class: an element matches when it contains (or is followed by) another matching element. It enables parent-state styling that previously required JavaScript or extra classes.
.form-group:has(:invalid) {
border-color: var(--danger);
}
.card:has(img) {
grid-template-columns: 8rem 1fr;
}
nav:has(+ main > h1) {
margin-block-end: 0;
}
Use scoped selectors — styling a card when it contains an image is clear; styling half the DOM from one :has is not. Check browser support and provide progressive enhancement.
On interviews: parent selection use cases, progressive enhancement, and selector cost awareness.
Common pitfalls: overly broad :has rules; replacing application state logic that belongs in JS or ARIA.
The trade-off is less boilerplate markup versus harder-to-reason selector graphs.
Checklist:
- Scope :has to clear component boundaries.
- Use for visual state, not hidden app logic.
- Plan fallbacks where support is required.
- Review selector performance on large trees.