Dec 17

CSS animation-composition

Use the CSS animation-composition property for advanced control over how values are applied during keyframe animations.

By Tyler Gaw

MDN describes animation-composition as:

The animation-composition CSS property specifies the composite operation to use when multiple animations affect the same property simultaneously.

Put another way, it gives us the ability to instruct animations to apply property values in ways other than the default behavior. It’s not limited to multiple animations. Animation composition affects all animated properties regardless of whether an element has one or multiple animations applied to it.

There are three possible values for animation-composition: replace, add, and accumulate, where replace is the default.

You apply animation-composition to the same element that has an animation.

.single-animation {
animation: move 2s infinite;
animation-composition: accumulate;

If you have multiple animations, you can set animation-composition for each using comma-separated values in the same order as the animations.

.multiple-animations {
animation: move 1s infinite, shake 3s infinite, roll 2s infinite;
animation-composition: add, accumulate, replace;

How it works

Since replace is the default, its behavior is likely what you expect from animations. It’s how animations have always worked up until now.

For example, let’s say we have an element that we’ve moved towards the right with transform: translateX(50px). Then we apply a keyframe animation to it that translates it another 200px on the x-axis, translateX(200px). The element was at 50px and is now at 200px.

If we change the element’s animation-composition to add or accumulate, we change the result of the animation. The element still starts at 50px, but now ends up at 250px on the x-axis because the 200px is added to the initial 50px.

See the CodePen.

What we’re seeing here with add and accumulate is basic math: 50 + 200 = 250. This is a simple example; we’ll see later that this basic math doesn’t apply to all combinations of composition and properties.

Effect on color

We’re not limited to positional properties. animation-composition impacts all animatable properties. And color properties produce interesting results.

Consider another example where we have an element with a background color of rgb(159, 0, 10). Then we apply an animation that animates the background color to rgb(129, 255, 30). The replace composition does as its name says; it interpolates from the start value to the end value just as it’s declared. With add and accumulate, the value of each channel – in this case, r, g, b – in the starting color is added to the corresponding channel of the ending color. Because this is rgb, each channel is capped at 255. We end up with the following:

The ending background-color for add and accumulate is rgb(255, 255, 40).

See the CodePen.

This example uses rgb, but a similar operation happens with hsl, hex, or a mix of color formats.

add vs accumulate, and the curious scale

In the examples so far, add and accumulate look the same. They do behave differently, but depending on the animated properties, there may not be a visible effect, or it may just be subtle. Let’s look at another example that shows a clear difference between the two and also shows that not all properties behave the same way.

In this example, we’ll animate a scale transform. Our elements start at scale(0.5) and animate to scale(2). We know the final scale value for replace will be 2 or 200%. Looking at our previous examples, you would think we’d do the same basic math for add and accumulate where both would do 0.5 + 2 and end up with a scale of 2.5 or 250%.

But that’s not how scale behaves. Take a look at the example and keep an eye on the scale values in the table.

See the CodePen.

We end up with scale of 1 for add and a scale of 1.5 for accumulate. Hrm, strange. But, it's good that we’re finally seeing the two operations produce different results.

What’s the math here, though? 0.5 + 2 should be 2.5, right? Why isn’t that happening, and what is the math behind this? Unfortunately, I couldn’t find an answer before the publish deadline for this post. This does work the same in all browsers, so it doesn’t seem like a bug. Some underlying logic for scale must make these the intended results. If you know the reason, please write about it!

Even with this, you still get more control over scale – and any other properties that work the same way – it just takes some trial and error to get to the exact values you need.

Browser support

Support for animation-composition is good. According to MDN, recent versions of all major desktop and mobile browsers support the property. 

The standard caveat does apply here, though. While this property is implemented in browsers, it is still a W3C editor’s draft in CSS Animations Level 2. That means the spec could change, and/or browsers may implement it differently. Always test in multiple browsers.

Using it

This is an interesting property. It’s likely not something you’ll use every day or even very often. It feels like something you’ll reach for when you’re trying to accomplish something very specific. That’s what makes it cool. It’s a low-level control for when you know exactly what you’re going after. And, if not that, it’s also helpful to toss on different values to play with random effects. Both are great reasons to use it. This property needs a healthy amount of trial and error to figure out how to make it work for you.

All the demos in this post and a couple more are available at


Tyler Gaw

Tyler Gaw

Tyler is an engineer and designer. He's spent his career in tech betting on The Web and pushing to help others see it for all it can be.

Tyler selected The Lower Eastside Girls Club for an honorary donation of $50

The Lower Eastside Girls Club

The Lower Eastside Girls Club amplifies the inner power of young women and gender-expansive youth in New York City through our free, year-round innovative programs in STEM, Arts, Digital Media and Sound, Wellness, Civic Engagement, and Leadership.