I have various notification elements of different sizes, and I slide them up and out after a timer. I need to know the size of the notification box to know how much to move it, so that the other notifications below it slide into place smoothly.
I would like to do something like
notificationEl.current.style = `@keyframes slideOut { 100% { margin-top: ${amountToMove}, opacity: 0}}`;
but it doesn't work. I tried instead using Element.animate() inside the useEffect on mount, but this causes weird flicker behavior.
setTimeout(() => {
notificationEl.current.animate([{ opacity: 0 }, { marginTop: marginTop }], {
animationTimingFunction: "ease-out",
duration: 375,
});
}, 2625);
Is there a way closer to the first example that I can assign a variable to margin-top inside the keyframe? Ideally, I'd want to do this in the useEffect on mount.
A little more explanation:
There is a fixed position notifications container on the right with no inherit size. It gets populated by specific notifications that slide in from the right and are arranged in a column. When the topmost one slides out, the one's underneath should slide in to occupy the space left by the first one, and this should happen as the slideout animation for the first notification occurs, so it looks smooth. Using translate or "top" don't get the bottom ones to move up until the first one unmounts. Collapsing height isn't what I want either, as that affects the look of the notification that's making its way out.
I have to make the margin-top in the keyframe the size of the bounding client rect plus an offset (that's what amountToMove indicates) because the sizes of the notifications can and do vary so the amount to move them by in order to make the animation look smooth also varies.
For my purposes, a nice solution was using
notificationEl.current.style.setProperty("--marginTop", `${amountToMove}`);
and then in the stylesheet keyframes declaration, use the variable:
@keyframes slideOut {
100% {
margin-top: var(--marginTop);
opacity: 0;
}
}