Skip to content
AITroveRead. Build. Understand.
Make this comfortable

CSS :has: style a parent from a meaningful child state

Last updated: 5 Oct 20265 min read
tutorial
BeginnerBy AITrove Editorial

The :has() relational pseudo-class matches an element when a selector relative to it matches. It can express a parent-child state relationship in CSS.

How the rule works

A receipt field wrapper needs a stronger border when the input inside it is invalid. The wrapper rule can look for that native state, while the input remains the element that owns validation. Scope the search to a small component instead of writing a document-wide rule that relates distant content. The wrapper should not become the only error message; include visible error text after a rejected submission. A blank required input may match :invalid before the person has tried to submit, so decide whether the timing matches the product's feedback policy.

css
.receipt-field { border: 1px solid #71869a; padding: .75rem; }
.receipt-field:has(> input:invalid) { border-color: #9b3030; }
.receipt-field:has(> input:focus-visible) { outline: 2px solid #205c8a; }

Cost and verification

The selector adds no JavaScript or network transfer. It can still cause more style matching than a simple class when used broadly, so profile an actual large page before making a performance claim. Test supported browsers and an unsupported-browser fallback: the base border remains usable even when :has is ignored. Keep the native input's own focus indicator as well, since the parent outline may not be close enough to identify the focused control.

Common Mistakes

  • Do not use :has as the only source of validation text.
  • Do not apply a broad relational selector to every element on a large page without measurement.
  • Do not remove the input focus indicator because its wrapper now changes.

Connected lessons

Related component decisions

css
selectors
web
Storage details