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.