References

Beginner-friendly references for web development, with live, editable examples.

The CSS :has() selector

Selector CSS All modern browsers Updated
Quick answer

The CSS :has() pseudo-class selects an element based on what it contains.card:has(img) matches cards that contain an image. It is the long-requested "parent selector," letting you style an element from its descendants or even its later siblings, which previously required JavaScript.

Overview

:has() answers a question CSS could not ask for two decades: "does this element contain something matching X?" .card:has(img) selects the cards that have an image inside them, and styles the card — not the image. Because it lets a parent react to its children, it is universally known as the parent selector.

Its reach goes well beyond children. label:has(+ input:focus) styles a label when the input next to it is focused; form:has(:invalid) styles a whole form while any field inside is invalid; .gallery:has(:hover) can dim a gallery whenever any item is hovered. Combined with the sibling combinators, it can even react to what comes after an element — something no selector could do before.

This unlocks a huge amount of UI that used to need JavaScript: layouts that adapt to their content, forms that respond to their own validity, components that style themselves based on their parts. Browser support is now solid across the board, so it is ready for everyday use.

Syntax

/* a card that contains an image */
.card:has(img) { … }

/* a form with any invalid field */
form:has(:invalid) .submit {
  opacity: 0.5;
}

Example

Live example
<style>
  .card { border: 2px solid #e2e8f0; border-radius: 10px; padding: 14px; font: 15px system-ui, sans-serif; margin-bottom: 8px; }
  .card:has(.badge) { border-color: #1c7ce9; background: #eff6ff; }
  .badge { background: #1c7ce9; color: #fff; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; }
</style>
<div class="card"><span class="badge">New</span> This card contains a badge, so :has() highlights it.</div>
<div class="card">This plain card is left alone.</div>

Best practices

  • Use it to style an element from its contents — the parent selector pattern that once needed JavaScript.
  • Combine it with sibling combinators (:has(+ input:focus)) to react to neighboring elements.
  • Reach for form:has(:invalid) and similar to drive UI from state without scripting.
  • Keep the inner selector reasonably simple for readability; :has() can express a lot, so clarity matters.

Frequently asked questions

What is the CSS :has() selector?
A pseudo-class that selects an element based on what it contains, e.g. .card:has(img) matches cards with an image. It is the long-awaited parent selector.
Is there a parent selector in CSS?
Yes — :has(). .parent:has(.child) styles the parent when it contains a matching child, which was impossible before.
Can :has() react to sibling elements?
Yes. Combined with combinators it can, e.g. h2:has(+ p) matches an <h2> that is immediately followed by a paragraph.
Is :has() supported in browsers?
Yes, it is supported across all current major browsers, so it is safe for everyday use.