要使颜色悬停变化平滑,须在常态规则中声明 transition: color 0.25s cubic-bezier(0.4, 0, 0.2, 1),统一用十六进制色值,并确保全程对比度≥7:1。

用 transition 控制颜色变化的时机和节奏
直接写 color 或 background-color 的悬停样式不会自动动起来,必须显式声明过渡行为。关键不是“加不加 transition”,而是加在哪、过渡什么、持续多久、用什么缓动。
-
transition要写在**常态规则里**(比如li或a上),不是只写在:hover里 - 只过渡颜色时,推荐写具体属性:
transition: color 0.3s ease;,避免用all引发意外动画(比如意外触发边框或阴影变化) - 时间值别设太长(超过 0.4s 容易被感知为卡顿),也别太短(低于 0.15s 几乎看不出过渡)
选对缓动函数影响真实感
ease 是默认值,但它的起始加速+结尾减速对颜色变化其实有点“过重”。颜色是线性感知的属性,用 ease-in-out 或更平滑的 cubic-bezier(0.4, 0, 0.2, 1)(即 ease-out 的现代等效)会更自然。
-
linear太机械,人眼容易觉得“生硬” -
ease-in开头突兀,ease-out结尾拖沓,都不适合纯色切换 - 如果项目已引入自定义缓动,优先复用统一的
--easing-smooth变量,保持动效语言一致
注意文字颜色过渡的可访问性陷阱
颜色过渡本身没问题,但若常态和悬停态的对比度都勉强达标(比如 4.4:1),中间过渡帧可能瞬间跌破 WCAG 4.5:1 的最低要求,导致短暂不可读。
- 用浏览器开发者工具的“无障碍”面板实时检查悬停过程中的对比度曲线
- 避免从浅灰(
#999)直接过渡到深灰(#333)——中间段(如#666)常低于标准 - 稳妥做法:常态用足够深的文字色(
#222),悬停改用强调色(#007bff),全程保持对比度 > 7:1
li a {
color: #222;
transition: color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
li a:hover {
color: #007bff;
}
真正容易被忽略的是:过渡生效的前提是两个状态的颜色值**类型一致**。比如 color: red → color: #ff0000 可以动,但 color: red → color: hsl(0, 100%, 50%) 在部分旧浏览器里会直接跳变。统一用十六进制或 RGB,别混用命名色和 HSL。










