In-N-Out Animations: Popovers (Part 2/3)
In-N-Out Animations: Popovers (Part 2/3) êŽë š
We kicked this series off looking a animating in and out the <dialog> element. This time weâre going to look at popovers. That is, this modern beauty:
<button popovertarget="my-popover">
Toggle Popover
</button>
<aside popover id="my-popover">
Content of popover
</aside>
That âpopoverâ will open and close (i.e. change from display: none; to display: block;) automatically with the button press. But we want to animate that! In and out!
Admittedly, popovers are fairly similar to dialogs (but certainly have important differences), and that is part of the point. Weâre going to show off that our three-phase system we established in the first article transfers over to something else just fine.
Article Series
Demo so you an see what weâre doing:
Reminder: The 3-2-1 System
The important thing to remember about styling both the in and out of an element was styling all three states and in order such that the âon the way inâ styles have enough specificity to win over the open styles.
Itâs essentially like this
.element {
transition: ...;
/* 3 */
&:not(.open) {
}
/* 2 */
&.open {
}
/* 1 */
@starting-style {
&.open {
}
}
}
3-2-1 with Popovers
Popovers have their own special pseudo-class for determining if they are open or not, so we can apply it like like below. This time, weâll transition the opacity and rotate property. Anything is on the table! Thatâs just what weâre choosing this time.
[popover] {
--timing: .66s;
transition:
var(--timing) opacity,
var(--timing) rotate,
var(--timing) display allow-discrete,
var(--timing) overlay allow-discrete;
/* 3 */
&:not(:popover-open) {
opacity: 0;
rotate: 10deg;
transform-origin: top left;
}
/* 2 */
&:popover-open {
--timing: 0.2s;
opacity: 1;
rotate: 3deg;
}
/* 1 */
@starting-style {
&:popover-open {
opacity: 0;
rotate: -3deg;
}
}
}
Handling Reduced Motion
Weâre introducing movement on the page here. We should take care to not do that if the user doesnât want it. But the opacity change is fine. So weâd do it like this.
@media (prefers-reduced-motion: reduce) {
[popover] {
transition:
var(--timing) opacity,
/* rotate is removed! */
var(--timing) display allow-discrete,
var(--timing) overlay allow-discrete;
&, &:popover-open {
rotate: 0deg;
}
}
}
Note that weâve made the popover have no rotation. Thatâs not a requirement, you could leave it tilted if you want.
Noting a Safari Quirk
Positioning anchors for popovers are âimpliedâ in most browsers. And thatâs true of Safari as well. You can see when we open the popover, itâs positioned where the button that opened it is. But âon the way outâ it loses that anchor for some reason. Bug? Unsure. So in the demo weâre just being specific about the anchor and that fixes it.
Also, in Part 1, the âon the way outâ styles for the <dialog> have an issue with the inset property, so we set it explicitly to inset: 0; and that fixes Safari.
Article Series