var() 不能直接用于 top/left,必须用 calc() 补单位或变量定义时自带单位;transform 更适合动态偏移但需注意 Safari 兼容性;@property 是实现 CSS 变量过渡的必要条件,Safari 暂不支持。

top/left 直接用 var() 会失效,必须套 calc()
浏览器对 top、left 等定位属性要求严格:值必须带单位(如 12px、-0.5rem),而 var(--offset) 若变量本身没单位(比如定义成 --offset: -8),整个声明会被静默丢弃——控制台不报错,但计算值回退为 auto。
正确做法只有两种:
-
--offset-y: -8px—— 变量定义时就带单位,后续可直接用于calc() -
top: calc(var(--offset-y) + 4px)—— 即使变量是--offset-y: -8,也得靠calc()补单位,但这种写法易出错,不推荐
别写 top: var(--offset-y),哪怕变量带单位,在多数浏览器里也无效。
transform: translate() 比 top/left 更适合动态偏移
transform 对 CSS 变量更宽容,且不触发重排,性能更好。但仍有硬约束:
立即学习“前端免费学习笔记(深入)”;
-
translateX(var(--x))在 Chrome/Firefox 可用,Safari 16.4+ 才稳定;旧版 Safari 必须写translateX(calc(var(--x) * 1px)) - 变量值必须含单位:
document.documentElement.style.setProperty('--x', '24px')✅,'24'❌ - 不能混用单位:
translate(calc(var(--x) * 1px), var(--y))中若--y是1.2rem,整条声明可能被忽略
推荐统一用 px 或 rem,避免在同一个 transform 中交叉使用。
@property 是实现平滑过渡的必要条件
想让 --offset-x 改变时带动画(比如 hover 或 JS 更新后渐变移动),光写 transition: transform 0.3s 不够——CSS 变量默认无类型,浏览器无法插值。
必须注册:
@property --offset-x {
syntax: '<length-percentage>';
inherits: false;
initial-value: 0px;
}注意:
-
syntax: '<length-percentage>'</length-percentage>是关键,它允许px、%、vh等合法混合参与运算 - Safari 目前(v17.6)仍不支持
@property,JS 动态更新后需手动触发重绘(如改style.transform) - 没注册时,变量变更只会“跳变”,不会过渡
JS 修改变量时最容易漏掉的三件事
用 element.style.setProperty() 或 document.documentElement.style.setProperty() 设置变量,常因细节失效:
- 作用域错:变量定义在
:root,却往子元素上设,后代拿不到 - DOM 未就绪:脚本执行早于 HTML 解析,
document.documentElement存在但样式未挂载,变量不生效 - 单位拼错:写成
el.style.setProperty('--y', y + 'px')✅,但y是字符串'-12'时,结果变成'-12px'—— 多了个负号,偏移反向
最稳的方式是:确保变量定义在 :root,JS 统一操作 document.documentElement,所有数值输出前做 parseFloat() 校验,再拼单位。


















