Entry transitions with @starting-style

Baseline 2024 Reference ↗

A newly displayed element may have no previous rendered style to transition from. @starting-style supplies that starting point. This popover fades in when opened and fades out when dismissed.

<style>
  #message {
    opacity: 0;
    transition: opacity .2s,
      display .2s allow-discrete,
      overlay .2s allow-discrete;
  }

  #message:popover-open {
    opacity: 1;
  }

  @starting-style {
    #message:popover-open { opacity: 0; }
  }

  @media (prefers-reduced-motion: reduce) {
    #message { transition: none; }
  }
</style>

<button type="button" popovertarget="message">Show message</button>
<div id="message" popover>A small message.</div>  

@starting-style sets the entry opacity to zero; :popover-open supplies the visible state. Keep the starting rule after the open-state rule so it wins when specificity is equal.

display and overlay use allow-discrete so removal from layout and the top layer can wait until the exit transition finishes. They do not gradually interpolate like opacity.

The starting-style rule is Baseline 2024. A browser needs the related popover and discrete-transition features for the full example; if entry animation is unavailable, the message should still open. Reduced-motion preferences disable the transitions.