The Dialog Element with Entry *and* Exit Animations
The Dialog Element with Entry *and* Exit Animations êŽë š
Una Kravets blogged the other day that animating entry effects are now supported in the latest stable version of all major browsers. The new cool way to do it, that is. Weâve long had trickery like applying a @keyframe animation with a to frame that would behave like an âentry effectâ, but it was a bit awkward and didnât work in all situations. Specifically one like using the new and very useful <dialog> element.
This bit of code says a lot:
dialog[open] {
transition:
translate 0.7s ease-out,
display 0.7s ease-out allow-discrete;
/* Post-Entry (Normal) State */
translate: 0 0;
/* Pre-Entry State */
@starting-style {
translate: 0 100vh;
}
}
There are two big things at work there:
- The
displayproperty is listed in the transitions, with the keywordallow-discrete. The code for it is hidden in User-Agent stylesheets, but when a<dialog>moves from close (default) to open, thedisplaygoes fromnonetoblock. Using this keyword means that thedisplayproperty is changed after the animation timing, so animations can actually happen. - The
@starting-stylegives us an opportunity to apply styling to the element just as itâs entering itâs current state, meaning the transition will happen between the styles declared inside and outside that block.
Golf clap. Everything is awesome.
What Una didnât cover, on purpose surely, was exit animations (because they arenât in âBaselineâ yet, meaning not supported across browsers). But they are supported in Chrome-n-friends land, so I thought it was worth looking at. To me, they are just as interesting, cool, and useful as the entry kind.
Both Entry and Exit
The trick isnât terribly different than the code above, itâs just to have very specific styles for both the open and closed (i.e. :not([open]) states. Like this:
dialog {
--duration: 0.34s;
transition:
translate var(--duration) ease-in-out,
scale var(--duration) ease-in-out,
filter var(--duration) ease-in-out,
display var(--duration) ease-in-out allow-discrete;
&[open] {
/* Post-Entry (Normal) State */
translate: 0 0;
scale: 1;
filter: blur(0);
/* Pre-Entry State */
@starting-style {
translate: 0 8vh;
scale: 1.15;
filter: blur(8px);
}
}
/* Exiting State */
&:not([open]) {
translate: 0 -8vh;
scale: 1.15;
filter: blur(8px);
}
}
Check it out:
And a video in case youâre in a browser that doesnât support it yet:
Note that not only does it have entry and exit animations, but those states are different âwhich is very cool! Emphasizing that, hereâs one where I move the dialog along an offset-path so the exit is really a continuation of the path:
Usage with Popovers
This isnât exclusively for dialogs, you can make it work with whatever. But naturally open-closable things make the most sense. Like native popovers! Nils Riedemann has a nice demo here: