transition适合两态平滑变化,需触发条件且仅作用于可计算属性;@keyframes适用于多阶段、循环或精确控制的复杂动画;二者混用时animation覆盖transition,应避免冲突。

用 transition 做简单状态切换动画
适合按钮悬停变色、菜单展开收起这类“两态之间平滑变化”的场景。它不描述过程,只告诉浏览器“从 A 到 B 怎么过渡”。
- 必须有触发条件(比如
:hover、:focus或 JS 切换 class),否则不会动 - 只对可计算的 CSS 属性生效(
color、opacity、transform、width等),display、height(非 0 → auto)这类不可动画化属性会直接跳变 - 常用写法:
transition: opacity 0.3s ease, transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);—— 多个属性可分别指定时长/缓动,别漏逗号 - 别滥用
all:写成transition: all 0.3s容易意外触发无意义动画(比如字体抗锯齿变化),明确列出需要动的属性更稳
用 @keyframes + animation 控制复杂运动路径
当你需要循环播放、多阶段变化(比如先放大再旋转再淡出)、或精确控制中间帧时,@keyframes 是唯一选择。
-
@keyframes里只能写属性值,不能写选择器或媒体查询;名字要合法(不能以数字开头,别用连字符) -
animation是简写属性,至少得带名字和时长,例如:animation: bounce 1.2s ease-in-out 0.1s 2 both;对应name、duration、timing-function、delay、iteration-count、fill-mode -
animation-fill-mode: both很关键——它让动画首帧在开始前生效、末帧在结束后保留,否则元素常会“闪回”初始状态 - 性能敏感场景优先用
transform和opacity,避免触发布局(left、top、width)或重绘(background-color)
过渡和关键帧混用时的常见冲突
两者同时作用于同一元素同一属性时,animation 会覆盖 transition,但实际开发中容易因 CSS 优先级或时机问题导致行为异常。
- 比如给一个按钮同时写了
transition: transform 0.3s和animation: shake 0.5s,点击后又 hover,shake可能被中断或卡住——因为transform被两个来源竞争控制 - 解决思路:用 JS 控制 class 开关,确保同一时间只启用一种动画机制;或者把过渡逻辑全收进 keyframes(比如 hover 触发
animation: hover-in 0.2s) - 调试技巧:Chrome DevTools 的
Animations面板能实时查看当前激活的动画、时间轴、是否被暂停,比猜强得多
移动端要注意的兼容性细节
iOS Safari 对 transition 和 animation 的支持整体不错,但有些边缘行为不一致。
立即学习“前端免费学习笔记(深入)”;
-
will-change: transform在老版 iOS 上可能引发渲染错误(白屏、闪烁),不是所有场景都适合加;真要用,建议配合@supports (will-change: transform)条件加载 - 用
transform: scale(0)隐藏元素时,iOS 有时仍会响应点击事件,得额外加pointer-events: none -
animation-play-state: paused在部分 Android WebView 中失效,如果要做暂停/继续功能,建议改用 class 切换 +animation: none临时清空










