transition必须由事件触发才能执行,它仅响应css属性值的变化;animation则定义即播放,不依赖属性变化,支持多关键帧和持久样式修改。

transition 必须靠事件触发,否则不执行
这是最常被忽略的底层限制。transition 本身不主动运行,它只监听 CSS 属性值是否发生了“变化”——而这个变化必须由外部事件(如 :hover、:focus、:checked)或 JS 修改样式(如 element.style.width = '200px')来引发。没有变化,就没有过渡。
常见错误现象:
- 给元素直接写
transition: all 0.3s;,但没配:hover或 JS 更新,结果动画完全不出现 - 用
class切换样式,但新 class 的属性值和旧 class 完全一致(比如都写opacity: 1),导致无变化、无过渡 - 在页面加载时希望自动动一下,但
transition不支持 —— 它不会在 DOM 渲染完成时自动触发
使用场景很明确:用户交互反馈类动效,比如按钮悬停变色、下拉菜单展开、表单聚焦高亮。
animation 一定义就跑,不需要任何事件
@keyframes + animation 是真正“自启动”的动画机制。只要元素匹配了带 animation 声明的规则,浏览器就会立即开始播放(除非显式设了 animation-play-state: paused 或 animation-delay)。
关键点:
-
animation不依赖属性值是否“变了”,它按帧驱动,哪怕元素初始状态和第 0% 帧一样,也会从头播一遍 - 可以设
animation-iteration-count: infinite循环,或用animation-fill-mode: forwards让结束帧保持生效 - JS 可以通过
element.style.animation = 'none'临时禁用,再赋回原值重启,实现手动控制
典型用途:加载指示器(loading spinner)、背景浮动效果、页面进入动效、数据刷新闪烁提示。
transition 能改属性值,animation 不能持久改
这是影响逻辑设计的关键差异。当 transition 动画结束,元素的 CSS 属性值就是最终状态的值(比如 width 真的变成了 200px);而 animation 播放完后,如果没用 animation-fill-mode: forwards,元素会“弹回”到动画前的原始样式 —— 因为它只是视觉模拟,并未真实修改属性。
所以:
- 要做“点击后菜单展开并保持”,用
transition+ JS 切换 class 更稳妥 - 要做“图标旋转三圈后停在新角度”,必须加
animation-fill-mode: forwards,否则转完就复位 - 用 JS 读取动画中元素的
offsetWidth,transition过程中会随时间渐变,animation中则始终是初始值(除非用了forwards)
transition 只能描述两态,animation 支持多关键帧
transition 天然只有起始态(当前值)和结束态(新值)两个锚点,中间过程由浏览器自动补间。你无法控制第 30% 时的位置、第 70% 时的透明度。
@keyframes 允许你明确定义任意百分比帧,比如:
@keyframes wiggle {
0% { transform: rotate(0); }
25% { transform: rotate(-5deg); }
50% { transform: rotate(5deg); }
100% { transform: rotate(0); }
}
这种节奏感、弹性、中途暂停/反向的需求,transition 无法满足。强行用多个 transition 嵌套模拟,代码难维护、时机难对齐、性能也更不可控。
容易被忽略的一点:哪怕只用 0% 和 100% 两帧,animation 仍比 transition 多一层控制权 —— 它可以独立设置每帧的 transform、opacity、color 等,而 transition 若想同时动多个属性,得确保它们都在 transition-property 列表里,且共用同一套 duration 和 timing-function。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











