Demos / Modern CSS

Three modern selectors. One page.

:has(), container queries, and dynamic viewport units — each with a tiny working demo and the rule that makes it go.

1. The parent selector — :has()

The whole form below is a single CSS rule. The label glows when its input has focus. The submit button dims while any input has a :invalid value, because .form-demo:has(input:invalid:not(:placeholder-shown)) matches the parent.

2. Container queries — @container

Both cards below have the same markup. The left one sits in a narrow column, the right one in a wide column. The card's own width decides whether it lays out vertically or horizontally — not the viewport.

Narrow column

Below 420 px, I stack.

Wide column

Above 420 px, I sit on a row.

3. Dynamic viewport units — dvh

On Safari, scrolling collapses the toolbar and the visible viewport height grows. 100dvh tracks the current height and resizes accordingly, while 100vh stays fixed at the large size. The box below is 50dvh.

I am 50dvh tall. Pull-to-refresh me on iPad to feel it.

Also available: svh (small) and lvh (large) for the locked extremes.