CSS动画中@keyframes不支持单属性独立时长,所有属性共享同一动画周期;实现多属性不同速度需拆分为多个动画、分层DOM或合并transform配合贝塞尔曲线;transition天然支持per-property时长但依赖状态变化。

关键帧里不能直接写 transition-duration
CSS 动画中,@keyframes 规则本身不支持为单个属性指定独立的缓动时长(比如让 transform 用 0.3s、opacity 用 0.8s)。你写的每个关键帧只是“快照”,浏览器会自动在相邻关键帧之间对所有声明的属性做线性或按 animation-timing-function 插值——所有属性共享同一段动画周期。
想实现多属性不同速度,得拆成多个动画或用 transform 分层
真正可行的解法是把节奏不同的属性剥离开:
- 给元素本身加一个主
animation,只控制节奏统一的属性(如opacity) - 再用伪元素或子容器包裹另一个节奏不同的属性(如快速缩放 + 慢速位移),单独设
animation - 或者全用
transform合并:把位移、缩放、旋转写进同一个transform值里,靠贝塞尔曲线模拟“局部快慢”,但这需要反复调参,不可控
例如:让图标淡入(0.6s)同时内部圆点脉冲(0.2s 无限循环),就该让圆点作为子元素,自己声明 animation: pulse 0.2s infinite,父容器只负责 animation: fadeIn 0.6s。
animation-timing-function 对整个动画生效,不是单属性
animation-timing-function(如 cubic-bezier(0.1, 0.7, 0.2, 0.9))作用于整个动画周期,影响所有在关键帧中变化的属性。它不能像 transition 那样写成 transition: opacity 0.6s, transform 0.2s 这种分属性声明。
立即学习“前端免费学习笔记(深入)”;
如果你看到某段代码似乎实现了“不同速度”,大概率是:
- 用了多个
animation层叠(比如animation: fade 0.5s, slide 1.2s),且两个动画的animation-duration不同 - 关键帧中某些属性只在起始/结束帧出现(比如
opacity只在 0% 和 100% 写,而transform在 0%/50%/100% 都有值),视觉上造成“分段节奏”错觉 - 混用了
transition和animation,比如 hover 触发 transition 控制颜色,同时 animation 控制旋转
真正要精细控制每个属性的起止和速率,还是得回到 transition + JS 触发
纯 CSS 动画做不到 per-property duration,但 transition 天然支持。只要状态变更可预测(比如 class 切换),就可以:
- 用
transition: opacity 0.4s ease-out, transform 0.15s cubic-bezier(0.3, 0, 0.5, 1) - 配合
element.classList.add('active')触发 - 如果需要延迟某属性启动,加
transition-delay,比如transform 0.15s 0.05s表示延迟 50ms 开始动
注意:transition 的限制在于它依赖状态变化,无法做无限循环或复杂路径;而 animation 更适合定义固定节奏的循环动效。两者不是替代关系,是分工关系——别硬用 keyframes 去啃 transition 的活。










