CSS变量本身不可过渡,transition写在自定义属性上会被浏览器静默忽略;必须作用于background-color等原生可动画属性,并确保颜色格式统一(如全用hsl或全用十六进制)才能实现平滑过渡。

CSS变量本身不能被过渡,var()只是取值占位符,不是可动画属性。你改的是字符串容器,浏览器根本不知道怎么算中间帧。
transition 写在 --color 上为什么无效
浏览器只对原生属性(如 background-color、transform、opacity)做插值计算。--color 是自定义属性,标准里明确不在可动画属性白名单中。
-
transition: --color 0.3s这行声明会被浏览器静默忽略,DevTools 的 Styles 面板里甚至不会显示「transitioning」状态 - 即使你在 JS 里调用
el.style.setProperty('--color', '#ff6b6b'),只要没在background-color上声明transition,就只有硬切 - 所有稳定版浏览器(Chrome/Firefox/Safari)都如此,不是兼容性问题,是规范限制
动画真正触发的链条必须完整
变量变化 → 触发依赖它的原生属性重算 → 该原生属性已有 transition 声明 → 浏览器启动插值
- ✅ 正确写法:
.btn { background-color: var(--bg); transition: background-color 0.3s ease; } - ❌ 错误写法:
:root { --bg: #fff; transition: --bg 0.3s; }(无效)或.btn { transition: --bg 0.3s; }(无效) - 如果
.btn继承了background-color但没显式写出值(比如留空或靠父级传递),transition也不会启动
颜色格式不一致会让过渡直接跳变
哪怕 transition 写对了,两端颜色格式不同也会导致插值失败——浏览器无法混合 #ffffff 和 rgb(10, 10, 10)。
- 统一用
hsl()最稳妥,支持 hue/saturation/lightness 分通道插值 - 或者全部用十六进制(
#000→#121212),或全部用rgb()(rgb(255,255,255)→rgb(10,10,10)) - 别混用:一边
hsl(0, 0%, 100%),一边#000,动画会在第一帧就跳到终点
最常被忽略的一点:变量更新后,必须确保使用它的原生属性在样式计算时能拿到新值——这意味着不能靠异步渲染(如 React 的 setState 后再改变量),也不能等 getComputedStyle 触发“重排”来“锁住起始值”,它压根不参与过渡调度。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











