Prisma says:has() is the long-awaited parent selector — style an element based on what it contains.
:has() finally lets CSS look downward: article:has(img) styles articles containing an image; label:has(input:checked) reacts to a checked child. It enables logic that used to require JavaScript — highlighting a card with an alert inside, styling an invalid form row, and more.
Power-ups you unlock
Style a parent by its descendants/state
article:has(img), label:has(:checked)
Replaces many JS-driven style toggles
A genuine parent/relational selector
Jank the Janitor attacks — common mistakes
Assuming older browsers support it
Overly broad :has() that matches too much
Performance worries from complex :has chains
Boss battleStyle a card differently when it :has(.badge).
Example code
<!doctype html><html><head><meta charset="utf-8">
<style>.card{padding:14px;background:#140a28;color:#e6e0ff;margin:6px}.card:has(.badge){border:2px solid #b388ff}</style></head><body style="background:#06040d;padding:20px"><div class="card">plain</div><div class="card"><span class="badge">★</span> has a badge</div></body></html>