Overview

:has() selects an element based on what it contains or what follows it: form:has(input:invalid) styles the form, and li:has(+ li) styles an item that has a next sibling. Prefer it over JavaScript that toggles parent classes when styling depends on child state. It is Baseline widely available (Chrome 105, Safari 15.4, Firefox 121).

Rules

  • Specificity equals its most specific argument, as with :is() and :not().
  • The argument is a relative selector list that is not forgiving: one invalid selector invalidates the whole rule. :has() cannot nest inside another :has() and does not accept pseudo-elements.
  • Test with @supports selector(:has(a)) only if you must support browsers from before December 2023.
.field:has(input:focus) label { color: var(--color-active); }
form:has(input:invalid) { border: 2px solid red; }