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;
}
}
Code language: CSS (css)
There are two big things at work there:
- The
display
property 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, thedisplay
goes fromnone
toblock
. Using this keyword means that thedisplay
property is changed after the animation timing, so animations can actually happen. - The
@starting-style
gives 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);
}
}
Code language: CSS (css)
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: