transition只能替代两态自动触发、无中间帧、不循环的keyframes动画,如淡入、悬停缩放、阴影增强;因其更轻量、稳定且易维护,而复杂多帧、带弹跳或需精确时序控制的动画则不可替代。

transition能替代哪些keyframes动画?
能替代的只有「两态自动触发、无中间帧、不循环」的动画。比如元素入场淡入、按钮悬停缩放、卡片展开时的阴影增强——这些用transition更轻、更稳、更易维护。@keyframes在这里属于“杀鸡用牛刀”,反而增加冗余代码和调试成本。
哪些keyframes写法可直接转成transition?
关键看是否满足三个条件:只涉及起始/结束两个状态;靠伪类(如:hover)或 class 切换触发;不需要animation-iteration-count或animation-direction等控制项。符合就可转,否则别硬转。
-
可转示例:一个弹入动画写成
@keyframes slideIn { 0% { transform: translateX(-20px); opacity: 0; } 100% { transform: translateX(0); opacity: 1; } },完全可用transform+opacity双属性transition实现,只要在 hover 或 active 时改这两个值即可 -
不可转示例:带弹跳效果的
@keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-20px); } },中间有明确回弹点,transition无法表达,强行拆成两次 class 切换会失去原子性和时序精度 -
注意边界:如果原
@keyframes用了animation-delay或animation-fill-mode: backwards,transition必须靠 JS 控制 class 添加时机或用transition-delay模拟,但无法真正复现 fill-mode 行为
transition替代时最容易踩的坑
不是语法不会写,而是对“可过渡属性”和“触发时机”的误判导致动效失效或卡顿。
-
transition: all 0.3s看着省事,但可能意外触发width、margin等引起 layout 的属性,造成掉帧;应只列transform、opacity、background-color等合成器友好的属性 - 想用
height: 0 → auto做展开动画?不行。auto无法插值,浏览器直接跳变;得用max-height设一个足够大的固定值(如max-height: 500px),再配overflow: hidden - 用
visibility: hidden → visible配合opacity做淡入?可以,但visibility本身不可过渡,必须靠opacity驱动视觉变化,且visibility要在过渡结束后才切换,否则元素会提前响应事件
性能差异到底在哪?
根本不在“谁更快”,而在“谁更可控”。transition由浏览器在合成器线程自动优化,只要只动transform和opacity,基本不占主线程;而@keyframes即使只定义两帧,也走完整 animation pipeline,多一层调度开销。但反过来说,一旦需要暂停、逆向、或 JS 动态控制进度(比如滚动驱动),transition就彻底没招——它没有 API,只有 CSS 状态。
真正容易被忽略的是:你写的那个“看似简单的 keyframes”,很可能隐含了 timing-function 分段、延迟入场、或与其它动画的时序耦合。这时候硬切到 transition,表面动效一样,实际交互链已经断了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











