transition必须写在默认状态而非:hover里,否则移出时无过渡;应指定可动画属性如background-color,避免all和渐变背景,注意移动端父级transform/opacity限制。

transition 必须写在默认状态,不能只写在 :hover 里
很多人把 transition 塞进 :hover 规则里,结果动画只在鼠标移入时生效、移出时直接跳变。这是因为 transition 只控制「属性变化过程」,而移出时没有它,浏览器就走默认的瞬时回退。
正确做法是把 transition: background-color 0.25s ease-in-out 写在按钮的默认样式块里(比如 .btn 或 button),:hover 只负责改颜色值。这样进出都有过渡。
- 推荐用
ease-in-out,比默认ease更柔和,尤其在 0.2–0.3s 这类短时长下更自然 - 别省略时间单位:写
0.3s,不是.3s或300ms(后者虽合法但易读性差) - 避免写
transition: all 0.3s——它会强行过渡 border、outline、font-size 等不相关属性,引发意外抖动
background-color 是唯一靠谱的颜色过渡属性
想让渐变背景「平滑变色」?直接写 transition: background 0.3s 几乎必然失败。因为 background 是简写属性,浏览器无法对 linear-gradient() 这类复杂值做插值计算。
真正能稳定过渡的只有 background-color,而且它只认纯色:十六进制(#4a6fa5)、rgb(rgb(74, 111, 165))、hsl(hsl(210, 40%, 47%))都行,但不能混用格式(比如 hover 时从 hsl() 切到 #000)。
- 初始状态必须显式声明
background-color,哪怕写transparent,否则 hover 里的新值可能被忽略 - 如果用了渐变,老老实实用伪元素模拟:主层过渡
background-color,::before叠一层固定透明渐变,视觉上像“渐变在变” - 移动端 Safari(尤其 14–15)对
background-image过渡支持极差,别赌兼容性
CSS 变量过渡失效,90% 是值类型不匹配
用 --btn-bg 和 --btn-bg-hover 看起来很优雅,但经常没动画——根本原因是变量展开后的最终值不可插值。比如 var(--btn-bg) 是 #3367d6,而 :hover 里设成 currentcolor,浏览器没法算中间帧。
要真平滑,两个变量值必须同类型、可线性插值:都用 hsl() 或都用 rgb(),且不能含 transparent(旧版 Safari 会拒插值,换成 rgba(0,0,0,0) 更稳)。
- 变量本身不触发重绘,过渡靠的是绑定它的属性(如
background-color: var(--btn-bg)) - 别在
:hover里动态算颜色:calc(var(--base) + 10)不合法,CSS 不支持颜色数值运算 - iOS Safari 14–15 对变量求值有延迟,尤其父级带
transform或opacity时,临时移除可验证是否是这问题
移动端 hover 失效,先查父级 transform/opacity
在 iOS Safari 上,按钮悬停没反应或动画卡顿,大概率不是代码问题,而是父容器动了手脚。Safari 有个隐藏限制:只要按钮的任意父级设置了 transform(哪怕是 translateZ(0))、opacity(哪怕 0.99)或 filter,子元素的 background-color 过渡就可能被静默禁用。
快速验证方法:临时删掉父级这些样式,看悬停是否恢复。若确认是此问题,有两个稳妥解法:
- 把
transition提前写到父容器上,子按钮继承生效 - 改用
box-shadow: inset 0 0 0 100px var(--btn-bg)模拟背景填充,box-shadow过渡兼容性比background-color更稳 - 务必加
cursor: pointer,否则部分 iOS Safari 版本根本不识别 hover 态
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











