Selectors and the cascade

:has()

Widely availablesince Jun 2026

Replaces: Toggling a class on a parent from JavaScript. A parent can be styled by what it contains: a card with an image, a form with an invalid field.

See it working

The syntax

.option:has(input:checked) {
  border-color: var(--brand);
  background: var(--brand-subtle);
}
The demo’s full CSS
.dm-has { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.dm-has label { display: flex; gap: 10px; align-items: flex-start; padding: 12px;
  border: 2px solid #dfe2ea; border-radius: 10px; background: #fff; cursor: pointer; }
.dm-has label:has(input:checked) { border-color: #4f46e5; background: #eef0ff; }
.dm-has span { font-size: 12.5px; color: #3d4450; }
.dm-has b { display: block; font-size: 14.5px; color: #0a0a0f; }

For browsers without it

Without :has() the selected option keeps its default border and the radio button still shows which one is chosen, so nothing is lost but the emphasis. No script needed either way.