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.