I have a notifications container which has fixed position on the right of the screen, but has no size by default. Each time a notification is rendered, it will populate the container, giving it width and height, and the notifications will appear one after the other in a column. I chose to use flex, but the same thing can be achieved without flex, and instead giving each child a margin-bottom for the gap.
.notifications {
position: fixed;
top: 5rem;
right: 1rem;
width: auto;
height: auto;
gap: 0.5rem;
display: flex;
flex-direction: column;
}
The notification itself has a lot of parts to it and the implementation isn't really relevant, so to simplify, Each notification has basic slide-in and slide-out animations:
.favorites-notification {
// other styles
transform: translateX(200%);
opacity: 0;
animation: slideIn 0.375s ease-out forwards, slideOut 0.375s ease-out 2.625s forwards;
}
@keyframes slideIn {
100% {
transform: translateX(0%);
opacity: 1;
}
}
@keyframes slideOut {
100% {
transform: translateY(-100%);
opacity: 0;
}
}
This looks pretty good when only one notification is rendered on the screen. However, when there are multiple notifications, in a top to bottom list, the remaining notifications will snap in place to the empty space left behind by the unmounted notification. Each notification's lifespan is set to 3 seconds with a setTimeout in useEffect on mount. How do I get the remaining elements to slide up to fill the position left by the unmounted notification, rather than just snap in place when the notification unmounts? I want the other notifications to slide up at the same time as the highest one is sliding up and out so it looks smooth.
I've tried collapsing the height of the notification to remove in the slideout animation, but it doesn't achieve the desired result and it's very unsmooth. I also don't want to affect the height of the notification that's sliding out because it lingers on the screen for a bit, and that's not the affect I'm going for. I know that translate doesn't affect document flow, so the DOM still thinks the element is where it originally was until it unmounts.
All help is appreciated. If my question/explanation isn't clear, please point that out and I'll revise it.
Edit: Using the top property didn't seem to work either. Setting negative margin-top is better, but it starts off smooth and still snaps at the end. To make negative margin work smoothly, I have to know the exact size of the notification, and that varies.