@starting-style / transition-behavior: allow-discrete

The modern CSS pair that lets dialogs, popovers, and display-none elements animate both as they appear and as they disappear.

my modal just appears with no animationmake a dialog fade in and out with only csspopover appears without a transitionanimate an element the first time it showsfade a popup out before it disappearswhy cant i animate display noneallow discrete cssstartng style

See it

Live demo coming soon

What it is

'@starting-style' supplies the before-change style an element needs when it first appears or returns from 'display: none'. Without it, a new dialog or popover has no earlier rendered state for a CSS transition to start from. 'transition-behavior: allow-discrete' is the companion that lets discrete properties such as 'display' participate in the transition.

Together they make native entry and exit motion practical for dialogs, popovers, and other top-layer UI. Chrome shipped both in version 117 in 2023, which is why this pattern replaced years of JavaScript timeout-then-unmount workarounds only recently. On entry, 'display' flips to the visible value at the start; on exit, it flips to 'none' at the end, so the opacity or transform transition remains visible. Transitioning 'overlay' as a discrete property can likewise keep top-layer content in place until its exit finishes.

Gotcha: a standalone '@starting-style' rule has normal cascade rules. Put it after the matching open-state rule when the selectors have equal specificity, or the open state can override it before the transition begins. These features create the CSS lifecycle, but focus management and dialog semantics still belong to the native dialog or popover API.

Ask AI for it

Animate this native dialog with CSS only. Give 'dialog[open]' opacity 1 and transform scale(1), then add a later '@starting-style' block where 'dialog[open]' starts at opacity 0 and scale(0.96). Set the closed styles to opacity 0 and scale(0.98), transition opacity and transform for 180ms, include display and overlay in the transition list, and set 'transition-behavior: allow-discrete' so both discrete properties wait through the exit. Keep the native showModal(), close(), focus trap, and Escape behavior, and remove the motion under 'prefers-reduced-motion: reduce'.

You might have meant

enter exit transitioncss transitionpopoverintrinsic size animationview transitions api

Go deeper