CSS过渡失效主因是transition未写在基础样式中、属性不可动画或浏览器未捕获起始帧;须将transition置于默认选择器,使用opacity/transform等可插值属性,并确保初始值明确。

过渡效果做不出来,八成不是浏览器问题,而是 transition 没写在对的地方、没配对可动画属性、或者状态切换时浏览器压根没机会拍到“起始帧”。
transition 必须写在基础样式里,不能只放 :hover 或 .active 中
鼠标一移开就“啪”地跳回原样?这是最常见症状。原因很简单:transition 被塞进了 :hover 规则里,离开时规则失效,动画直接被丢弃。
- 错误写法:
.btn:hover { transition: background-color 0.3s; } - 正确写法:
.btn { transition: background-color 0.3s ease; },再单独写.btn:hover { background-color: #1E5799; } - 基础类里必须有明确的初始值,比如
transform: scale(1),不能留空——否则移出时浏览器不知道该缩回哪去 - 如果用 JS 切 class,也要确保旧元素在移除 class 前已渲染出初始态(读一次
offsetHeight可强制固化)
只对 opacity、transform 等可插值属性做 transition
transition 不是万能胶,它只认「有中间值」的属性。写了也白写的典型有:display、height: auto、z-index、font-size(部分浏览器虽能动但不可靠)。
- 安全首选:
opacity、transform(位移/缩放/旋转),天然触发 GPU 加速,丝滑不卡 - 可用但需谨慎:
background-color、max-height(必须设具体数值,如max-height: 0→200px) - 别碰
width/height:触发布局重排,中低端设备上掉帧明显 - 别用
transition: all:它会监听padding、box-shadow等意外变化,节奏全乱
transitionend 事件必须过滤 propertyName
一个元素同时过渡 opacity 和 transform,transitionend 会触发两次。不加判断就执行状态更新,大概率只处理了一半,下一次切换就错位。
立即学习“前端免费学习笔记(深入)”;
- 监听时务必检查:
if (e.propertyName === 'transform')或if (e.propertyName === 'opacity') - 该事件不冒泡,必须绑定在目标元素本身,不能委托父级
- 不要用
setTimeout替代它——缩放设置、GPU 就绪延迟都会导致偏差 - 多步骤并行过渡时,每个
transitionend回调都要独立判断,避免互相干扰
移动端和旧版 Safari 的兼容性陷阱
iOS Safari 12–14 对 filter: brightness() 解析不稳定,容易闪白帧;Android Webview 和 iOS 9–12 需要 -webkit-filter 前缀;而纯 opacity 在触摸设备上又没点击反馈。
- 加
transform: translateZ(0)或backface-visibility: hidden强制硬件加速 - 亮度值保留 1 位小数,比如
brightness(0.7),别写brightness(0.7001) - 双写前缀:
filter: brightness(0.7); -webkit-filter: brightness(0.7); - 移动端补点击反馈:用
:active+transform: scale(0.98),别依赖:hover
真正卡住人的,往往不是“怎么加 transition”,而是“为什么加了没反应”——问题通常藏在初始值声明、DOM 更新时机、或属性是否真能插值这三个地方。漏查任一,动画就静默失效。



















