css变量本身不触发动画,因其非可动画属性;必须将其绑定到transform、opacity等原生可过渡属性上,通过声明这些属性的transition才能实现平滑效果。

CSS 变量本身不能直接触发 transition 或 animation,必须配合可动画属性(如 transform、opacity、color)才能产生过渡效果。
为什么直接给 CSS 变量加 transition 没反应
很多人写成这样:
:root {
--size: 10px;
transition: --size 0.3s; /* ❌ 无效!CSS 变量不是可动画属性 */
}
.box { width: var(--size); }
浏览器根本不会监听 --size 的变化并插值——它只认 width、transform 这类原生属性。变量只是“值的容器”,不参与渲染管线。
- 真正起过渡作用的是
width属性本身,但width默认不可过渡(除非是长度单位且有明确起止值) -
var(--size)是计算时才展开的,浏览器不会在变量变时自动重算并过渡width - 想让尺寸变化平滑,得把
width换成transform: scale()这类 GPU 加速属性
正确做法:用 transform + var() + transition
把变量绑定到支持过渡的属性上,比如 transform:
.box {
--scale: 1;
transform: scale(var(--scale));
transition: transform 0.3s ease;
}
.box:hover {
--scale: 1.3;
}
这段代码能动,是因为:
-
transform是可过渡属性,浏览器会自动插值从scale(1)到scale(1.3) -
var(--scale)在每次重绘时重新计算,值变了 →transform值跟着变 → 触发已声明的transition - 不需要 JS,纯 CSS 就能响应 hover、focus 等状态
JS 动态改变量时,如何确保过渡生效
用 el.style.setProperty('--scale', '1.5') 改变量后,如果没看到过渡,常见原因:
- 元素初始没有声明
transition,比如只在:hover里写了,JS 修改时不在 hover 状态下 → 过渡不触发 -
transition写在了伪类里(如.box:hover { transition: transform 0.3s; }),而 JS 修改发生在常态 → 必须把transition提到基础选择器中 - 变量名拼错,比如写成
--scle,var(--scle)返回无效值,transform退化为none,不触发过渡 - 修改后立即又被其他样式覆盖(比如父级
transform合并干扰),可用 DevTools 的 “Computed” 面板检查最终生效的transform值
多变量组合动画时的性能和兼容性注意点
像这样同时驱动缩放、旋转、位移:
.box {
--scale: 1;
--rotate: 0deg;
--tx: 0px;
transform: translateX(var(--tx)) rotate(var(--rotate)) scale(var(--scale));
transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1);
}
要注意:
- 所有变量必须在同一行
transform中使用,否则浏览器可能无法合并为单次 GPU 绘制 - Safari 15.4+ 才完整支持
var()在transform函数内的计算;iOS 15.0–15.3 会忽略整条transform声明 - 避免在
@keyframes中混用var()和固定值(如transform: translateX(var(--tx)) rotate(45deg)),部分旧版 Chrome 会丢帧 - 如果需要 IE 兼容,变量方案完全不可用,得退回预处理器(Sass/Less)或 JS 控制 class 切换
真正难的不是写法,而是判断哪个属性该交给变量控制、哪个该保留在 keyframes 里——变量适合用户交互驱动的动态参数,keyframes 适合时间轴明确的序列动作。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











