CSS变量不能直接transition,因其非可动画属性;需JS更新变量,CSS用calc()转为带单位值并绑定到transform等可过渡属性上,再配transition。

直接用 transition 对 CSS 变量做过渡是无效的——变量本身不触发重绘,浏览器根本不会监听它的变化。必须靠 JS 更新变量 + CSS 中用 calc() 驱动 transform,再配合 transition 作用于最终渲染属性。
为什么 var(--x) 不能直接 transition
CSS 变量是“值容器”,不是可动画属性。即使你写 transition: --mouse-x 0.2s,浏览器会静默忽略——CSS 动画规范里明确不支持自定义属性作为 transition-property 的合法值。真正能过渡的,只有 transform、opacity、box-shadow 这类原生可插值属性。
常见错误现象:--mouse-x 在 JS 里狂改,但元素位置毫无过渡感,直接瞬移。
- 别在 CSS 里写
transition: --mouse-x 0.2s,它不起作用 - 别指望
style.setProperty('--mouse-x', x)自带缓动,那只是赋值 - 过渡必须落在最终生效的属性上,比如
transform: translate(...)
正确做法:CSS 中声明 transition,JS 只更新变量
核心逻辑是:JS 负责把鼠标坐标写进 --mouse-x 和 --mouse-y;CSS 负责用 calc() 把变量转成像素,并绑定到可过渡的 transform 上。
示例结构:
.follower {
transform: translate(calc(var(--mouse-x) * 1px), calc(var(--mouse-y) * 1px));
transition: transform 0.2s cubic-bezier(0.22, 0.61, 0.36, 1);
}
-
calc(var(--mouse-x) * 1px)是必须的——var(--mouse-x)没单位,乘1px才能参与长度计算 -
transition必须写在 CSS 里,不能靠 JS 动态加style.transition,否则高频更新会丢帧 - 初始状态建议显式设
transform: translate(0, 0),避免首次过渡失效
移动端 touchmove 兼容要点
PC 的 mousemove 在手机上完全不触发,必须单独监听 touchmove,且坐标的获取和默认行为处理极易出错。
关键差异:
- 用
e.touches[0].pageX(不是clientX或changedTouches) - 加
{ passive: false }才能调用e.preventDefault(),否则安卓 WebView 可能返回0 - 务必加
touch-action: none到目标容器,否则系统手势(如缩放、滚动)会干扰坐标连续性 - PC 和移动端共用同一组变量名(如统一用
--mouse-x),CSS 层不用分支
容易被忽略的性能陷阱
看似只设两个变量,但若页面中多个元素都引用 var(--mouse-x) 并用于 transform,合成层压力会陡增,尤其在低端 Android 设备上掉帧明显。
- 只对真正需要跟随的元素加
will-change: transform,别写在body或通配符里 - 避免在
* { transform: ... }这类规则中引用鼠标变量,它会让所有元素都参与合成层重建 - 如果跟随元素有大量子节点,考虑用
contain: layout paint隔离渲染影响范围 - 滚动时坐标偏移?确认用的是
pageX/pageY,不是clientX/clientY——后者不包含滚动距离
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











