transition必须写在基础状态而非:hover中,否则移出时无动画;仅可动画化属性(如transform、opacity)支持过渡,需避免display等无效属性。

直接加 transition 就能生效,但绝大多数人第一次写完发现“只进不出”——鼠标悬停时动画正常,移开却瞬间跳回。问题不在语法,而在应用位置。
transition 必须写在基础状态,不能只写在 :hover 里
很多人把 transition 放在 :hover 选择器中,比如:
.btn:hover { background-color: #0056b3; transition: background-color 0.3s; }
这会导致移出时无过渡:因为离开 :hover 后,transition 规则失效,浏览器直接回退到初始值。正确做法是把 transition 写在元素的默认样式里:
-
transition必须定义在非伪类的基础选择器中(如.btn),才能覆盖“进入”和“离开”两个方向 - 即使只改一个属性,也要确保该属性在基础态和悬停态都有明确值(比如
transform: scale(1)和scale(1.05)) - 若基础态没设
transform,浏览器会从none开始过渡;但移出时若没显式重置,可能残留计算值,导致行为不一致
哪些 CSS 属性支持 transition?不是所有都能动
只有「可动画化」的属性才支持 transition。常见有效属性包括:
立即学习“前端免费学习笔记(深入)”;
-
opacity、transform(推荐优先用,触发 GPU 加速) -
background-color、color、border-color -
width、height—— 但会触发重排(layout),性能较差 -
max-height可用于展开/收起,但需设具体数值(0→200px),不能用auto
无效示例:display、z-index、font-size(虽可动但易引发重排)、margin(同理)。查 MDN 的「Animatable」标识最可靠。
transition 简写 vs 拆分写法:按需选择
简写形式简洁,但容易掩盖细节:
.btn { transition: background-color 0.3s ease, transform 0.2s ease-out; }
拆分写法更可控,尤其当不同属性需要不同持续时间或缓动函数时:
transition-property: background-color, transformtransition-duration: 0.3s, 0.2stransition-timing-function: ease, ease-out
注意:如果某属性只在悬停态设置(如新增 box-shadow),而基础态没声明,它仍会过渡——浏览器会从「无」插值到「有」,但效果可能不如预期。
transitionend 事件监听要防多次触发
用 JavaScript 监听过渡结束时,transitionend 会在每个过渡属性完成时都触发一次。例如同时过渡 background-color 和 transform,就会触发两次:
element.addEventListener('transitionend', (e) => {
if (e.propertyName === 'transform') {
// 只响应 transform 结束
}
});
- 务必检查
e.propertyName,避免重复执行逻辑 - 过渡被中断(如快速悬停又移出)时,
transitionend仍会触发,且e.elapsedTime小于设定时长 - 移动端需注意,
:hover在触摸设备上行为不稳定,建议搭配:active或 JS 切换 class
真正卡住人的往往不是怎么写,而是没意识到 transition 是双向契约:它只对「有起点、有终点、有路径」的属性变化起效。起点模糊、终点缺失、或属性本身不可插值,都会让动画静默失败。



















