CSS Quick Tip: Animating in a newly added element

Feb 21, 2022

I've solved the challenge of adding animation to a newly added DOM element several times by way of setTimeout to juggle classes that were tied to CSS transitions. Recently, a friend brought up that they were working on something similar, and it occurred to me that a switch to keyframes just might remove the need for JavaScript.

So, I whipped up a quick CodePen to vet the idea and sure enough, it worked!

This technique works because the animation begins playing when the element is added, removing the need to have to add a class to trigger a regular transition. The magic line is:

animation: show 600ms 100ms cubic-bezier(0.38, 0.97, 0.56, 0.76) forwards;

In this definition, show is the name of the keyframes animation. The first number of 600ms is the animation duration (how long it takes to play), and the second number of 100ms creates a small delay before the animation begins.

Then, instead of using a simple easing type such as ease-in, we're using a custom cubic-bezier function which in conjunction with the transition causes the final effect to feel like the element is gently expanding into place.

The last critical part is setting the animation-fill-mode to forwards so that the animation stops on the last frame, aka the 100% state. Without that, the element wouldn't stay visible.

A neat thing about CSS animations is that you don't need to define a starting state for a two-step animation. For this one, we define the starting state as the default style, and then only define the end state - so just 100% - within the keyframes.

@keyframes show {
100% {
opacity: 1;
transform: none;
}
}

Here's the CodePen with the effect altogether. The only JS in the pen is to allow you to add a new list item to simulate having items added in a "real" app.