这篇文章发布于 2025年05月12日,星期一,23:58,归类于 CSS相关。 阅读 7060 次, 今日 12 次 没有评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11689
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
一、前言
CSS animation-composition属性其实出来有一段时间了,2年多,见下面的附图,之前有见人分享过,最近有人在上一篇文章评论区提过,才想起了他,决定写篇文章简单记录下。

这个属性可以设置CSS动画效果再执行的时候,相关的CSS属性值是替换、直接相加还是计算累积。
二、animation-composition语法和案例
其语法如下所示:
/* 三个动画值 */ animation-composition: replace; animation-composition: add; animation-composition: accumulate; /* 多个动画 */ animation-composition: replace, add; animation-composition: add, accumulate; animation-composition: replace, add, accumulate;
这里出现了3个值replace, add, accumulate就是animation-composition支持的几个关键字值,其含义分别如下:
- replace
- 这是默认值。动画也就是
@keyframes{}声明的CSS属性会替换默认设置的CSS属性值。 - add
- 属性值直接相加。
- accumulate
- 属性值计算叠加。
accumulate和add比较类似,很多同学会搞不清楚,下面会有案例示意。
add和accumulate的区别
- add是纯粹的属性值相加。
- accumulate则是累加计算后的值。
在大绝多数情况下,add和accumulate两个值的表现是没有区别的,只有当CSS属性值相连和叠加的渲染效果不一样的时候才会有区别。
所以:
1. 普通CSS属性两者无区别
<canvas id="ball1" class="ball"></canvas>
<canvas id="ball2" class="ball"></canvas>
<p>
<button
onclick="ball1.classList.toggle('active');ball2.classList.toggle('active')"
>运动</button>
</p>
.ball {
width: 120px; height: 120px;
background: deepskyblue;
border-radius: 50%;
position: relative;
left: 100px;
}
#ball1.active {
animation: 2s move infinite;
animation-composition: add;
}
#ball2.active {
animation: 2s move infinite;
animation-composition: accumulate;
}
@keyframes move {
from { left: 50px }
to { left: 150px }
}
此时,两个球的运动轨迹是一模一样的(动画都是从150px位置~250px)。实际效果如下所示(点击“运动”按钮):
2. transform属性没区别
transform属性支持多值相加,但是值前后相连和直接合并计算的渲染效果是一样的,例如,还是上面的例子,我们将位移改为transform属性实现,会看到并无区别:
.ball {
/* 相同代码略 */
transform: translateX(100px);
}
#ball1.active {
animation: 2s move;
animation-composition: add;
}
#ball2.active {
animation: 2s move;
animation-composition: accumulate;
}
@keyframes move {
from { transform: translateX(50px); }
to { transform: translateX(150px); }
}
原因很简单,add关键字生效的时候,动画的计算表现其实是这样的:
from {
transform: translateX(100px) translateX(50px);
}
to {
transform: translateX(100px) translateX(150px);
}
accumulate关键字的计算表现则是(直接累加计算):
from {
transform: translateX(150px);
}
to {
transform: translateX(250px);
}
transform连续位移和一次性位移的效果是一样的,因此,大家看不出两者的区别。
但如果是filter属性的某些值,那就会有所区别。
3. filter属性的模糊函数的区别可见
我们先看静态效果,比方说有张图片,我们应用下面两段CSS代码的效果是不一样的:
img {
filter: blur(2px) blur(2px);
}
img {
filter: blur(4px);
}
前者还是2px模糊,后者是4px。
我们可以看一下下面的实际渲染效果(实时渲染):


所以,当我们的动画是模糊变化的时候,大家就可以看到add和accumulate两个值的区别了。
对此,我专门做了个演示页面,您可以狠狠地点击这里:add和accumulate渲染效果区别演示demo
鼠标悬停目标图形,就可以看到不同的模糊动画效果了。
例如,悬停右图(移动端是下图),明显可以感觉到要更加模糊一点:

相关测试代码如下所示:
<img src="1.jpg" class="img1"> <img src="1.jpg" class="img2">
img:hover {
filter: blur(2px);
animation: 1s pulse both;
}
.img1 {
animation-composition: add;
}
.img2 {
animation-composition: accumulate;
}
@keyframes pulse {
0% {
filter: blur(0px);
}
100% {
filter: blur(2px);
}
}
三、实际应用场景和结语
animation-composition属性最具代表性的应用场景当属transform动画了。
例如一个水平居中的toast在出现的时候需要有个轻微的上移动画,此时就不要担心translateX()函数和translateY()函数冲突的问题了。
<div id="toast" class="toast">操作成功!</div>
.toast {
position: fixed;
left: 50%;
transform: translateX(-50%);
background: green;
padding: 4px 8px;
color: #fff;
animation-composition: add;
display: none;
}
.toast.active {
display: block;
animation: tinyUp 350ms both;
}
@keyframes tinyUp {
0% { transform: translateY(20px); }
100% { transform: translateY(0px); }
}
实时渲染效果如下,点击按钮体验:
——
好,以上就是本文的全部内容,相信大家对animation-composition属性的理解一定更加全面了,感谢阅读,欢迎分享。
🦺👔👕👖🧣
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11689
(本篇完)
- 页面级可视动画View Transitions API初体验 (0.473)
- 不能落后,好好缕缕CSS滚动动画 (0.473)
- 使用CSS linear()函数实现更逼真的物理动画效果 (0.473)
- 使用CSS将图片转换成模糊(毛玻璃)效果 (0.467)
- 3种纯CSS实现中间镂空的12色彩虹渐变圆环方法 (0.467)
- FDCon2019大会分享之滤镜与混合模式实录 (0.467)
- 分享一个即插即用的私藏缓动动画JS小算法 (0.402)
- CSS backdrop-filter简介与苹果iOS毛玻璃效果 (0.402)
- 细说iOS Safari下focus的行为 (0.402)
- 这啥?CSS calc-size和interpolate-size,真学不动了 (0.402)
- CSS3+js实现多彩炫酷旋转圆环时钟效果 (RANDOM - 0.060)