hover退出时transition不生效是因为只在:hover中声明了transition,而默认状态未声明;必须在两个状态中都定义相同的transition属性才能实现正反向平滑过渡。

hover 退出时 transition 不生效?检查 transition-property 和 timing-function
默认情况下,transition 只在触发状态变化(如 :hover 进入)时起作用,但退出时失效,通常是因为只在 hover 状态上写了 transition,而普通状态没写或写错了。真正起作用的是「两个状态之间都定义了可过渡的属性」。
必须同时在默认状态和 :hover 状态中声明相同的 transition,否则退出时会“跳变”。例如:
button {
background-color: #007bff;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #0056b3;
}
这样退出时才会反向执行过渡。常见错误是只在 :hover 里写 transition,导致退出无动画。
transition-delay 在退出时无效?它只作用于触发后延迟开始,不控制反向延迟
transition-delay 是单向的:它只在状态变更后、过渡真正开始前等待指定时间,不管进入还是退出都不会自动翻转。如果想让鼠标离开后等 100ms 再开始淡出,得靠 JS 控制类名延时添加,纯 CSS 无法实现「退出专属 delay」。
立即学习“前端免费学习笔记(深入)”;
- 写在默认状态里的
transition-delay: 0.1s对进入生效,对退出也生效(即 hover 进入后等 100ms 才开始变色,退出后也等 100ms 才开始恢复) - 写在
:hover里的transition-delay只影响进入过程,退出时被忽略 - 真正需要「进快出慢」或「进慢出快」,得用两个不同 timing-function,比如
ease-in和ease-out
伪元素动画退出卡顿?确保 transform 或 opacity 的初始值可被浏览器硬件加速
用 ::before 或 ::after 做遮罩/滑入效果时,常遇到退出时不平滑,甚至直接消失。根本原因是初始状态未设置 opacity: 0 或 transform: translateX(-100%),导致浏览器无法建立过渡上下文。
正确写法示例(下划线滑入):
a {
position: relative;
color: #333;
}
a::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: #007bff;
transition: width 0.3s ease;
}
a:hover::after {
width: 100%;
}
这里 width 从 0 → 100% 进入,再从 100% → 0 退出,完全可逆。若用 display: none/block 或 visibility,则无法过渡。
transition 失效于 display 或 visibility?这些属性本身不可过渡
display、visibility、z-index、font-weight(非数值)等属性不能参与 transition。试图给 display: none 加过渡,结果就是“瞬间消失”,没有反向过程。
替代方案:
- 用
opacity+pointer-events模拟隐藏(opacity: 0; pointer-events: none;) - 用
transform: scale(0)或translateY(-20px)配合opacity实现更自然的进出 - 需要真正销毁 DOM 时,用 JS 监听
transitionend后移除元素,而非依赖 CSS
过渡是否反向执行,本质取决于「两个状态是否都声明了同一组可动画属性」,而不是 hover 本身有魔法。最容易被忽略的是:过渡属性必须在默认状态就存在,且不能被 hover 覆盖掉 —— 否则退出时浏览器找不到“回去的路”。


















