transition必须写在默认状态而非:hover中,否则移入有动画、移出跳变;颜色需统一用hsl()或rgba()格式以确保插值稳定,background-color与渐变不可直接过渡。

transition 写在 :hover 里颜色就跳变?必须写在默认状态
颜色过渡失效最常因为 transition 被误写在 :hover、.active 这类目标状态中。浏览器只在初始渲染时检查元素是否声明了过渡,不是看新样式有没有加 transition。
✅ 正确写法:.btn { color: #333; transition: color 0.3s ease; } + .btn:hover { color: #007bff; }
❌ 错误写法:.btn { color: #333; } + .btn:hover { color: #007bff; transition: color 0.3s ease; }
原因很简单:移入时触发过渡,移出时没有 transition 声明,直接回退——看起来就是“进有动画、出没动画”或全程跳变。
hex → rgb 或 hsl → rgba 混用会导致插值中断
CSS 颜色插值依赖格式一致性。起始值和结束值若用不同表示法(比如 #ff6347 → rgb(255, 105, 71)),部分浏览器无法稳定插值,尤其 Safari 和旧版 Chrome。
- 优先统一用
hsl()或rgba():它们天然支持通道级线性插值,过渡更顺滑 - 避免
#000→white、currentColor(未显式定义时)、inherit等不可插值值 - 透明度变化建议用
rgba(0,0,0,0.8)→rgba(0,0,0,0),而非transparent(Safari 15–16 对transparent插值不一致)
background-color → linear-gradient 不能直接 transition
background-color 和 background-image: linear-gradient() 是两个完全独立的属性,CSS 不支持跨类型插值。写了 transition: background 0.3s 后把单色换成渐变,结果一定是跳变。
立即学习“前端免费学习笔记(深入)”;
可行解只有两种:
- 始终用
linear-gradient,只动 color stop 的颜色值,且保持所有位置参数(如0%、100%)不变 —— 例如:background: linear-gradient(to right, #ff6347, #1e90ff);→background: linear-gradient(to right, #ff7e5f, #feb47b); - 用
::before伪元素覆盖一层渐变背景,再对它的opacity做transition,底层保留纯色
注意:Chrome 120+ 实验性支持 background-image 中 color stop 的直接过渡,但 Firefox 和 Safari 仍未跟进,生产环境别赌。
@keyframes 动画里改颜色比 transition 更可控
当需要多段颜色变化、循环、或精确控制中间态(比如红→黄→绿→蓝),@keyframes 比 transition 更可靠。
示例(三色循环):
@keyframes hue-cycle {
0% { background-color: #ff6347; }
33% { background-color: #ffcc00; }
66% { background-color: #00cc66; }
100% { background-color: #007bff; }
}
.box { animation: hue-cycle 4s ease-in-out infinite; }
关键点:
- 所有关键帧都用同一种颜色格式(推荐
hsl(),方便调节色相/饱和度/亮度) - 避免在
@keyframes里混用background-color和background-image - 如果要兼容 iOS 12/Safari 12,加一行
-webkit-animation
真正难的不是写出来,而是让不同浏览器在各种设备上都保持同一套插值逻辑——所以格式统一、属性隔离、渐变只动 color stop,这三条是绕不开的硬约束。


















