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.
replace
: The effect value overrides the underlying value of the propertyadd
: The effect value builds on the underlying value of the propertyaccumulate
: The effect and underlying values are combined
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
.
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:
r
: 159 + 129 = 288, so we’re capped at 255g
: 0 + 255 = 255b
: 10 + 30 = 40
The ending background-color
for add
and accumulate
is rgb(255, 255, 40)
.
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.
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.
- Chrome 112
- Firefox 115
- Safari 16
- Edge 112
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 https://codepen.io/tylergaw/pen/VwgmrMY.
Reference
#- animation-composition on MDN
- animation-composition in CSS Animations Level 2 Editor’s Draft
- Demos from this post https://codepen.io/tylergaw/pen/VwgmrMY
Tyler selected The Lower Eastside Girls Club for an honorary donation of $50
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.