demo · v133

:has(:open) — ancestor reacts to descendant state

The real power of :open appears when you combine it with :has(). The page, the toolbar, even body can react to whether any descendant widget is open — without a single line of JavaScript.

A panel is open — the page background dimmed to focus your attention.

toolbar — recolours when <select> picker is open

filter: sort:

accordion list — page reacts when any item is open

Panel one

Some content.

Panel two

More content.

Panel three

Even more content.

the rules

/* Page dims when any panel is open */
body:has(details:open) .stage { background: var(--bg-stone); }
body:has(details:open) .floating-hint { display: block; }

/* Toolbar recolours when one of its <select> pickers is open */
.toolbar:has(select:open) { background: var(--accent-blue); }
.toolbar:has(select:open) select { background: white; color: black; }

Three classic UI patterns now expressible in CSS only:

see also