box-shadow 配合 css 变量失效是因为变量不携带单位,直接拼接 px 语法错误;正确做法是用 calc(var(--x) * 1px) 将无单位数字转为合法长度值,并配合 transition box-shadow 实现动画。

为什么直接用 box-shadow 配合 CSS 变量会失效?
很多人试过写 --shadow-x: 2px; --shadow-y: 4px; 然后在 box-shadow: var(--shadow-x) var(--shadow-y) 8px rgba(0,0,0,0.1);,结果阴影根本不动——因为 box-shadow 的前两个参数必须是带单位的长度值(如 2px),而 CSS 变量本身不携带单位语义;当你只存数字(--shadow-x: 2)再拼接 px,CSS 不支持字符串拼接,会直接解析失败。
用 calc() 动态组合偏移量才是正解
必须把单位“固化”在 calc() 表达式里,让浏览器在运行时计算出合法长度值。变量只存纯数字,单位由 calc() 显式提供:
card {
--shadow-x: 2;
--shadow-y: 4;
--shadow-blur: 8;
--shadow-alpha: 0.1;
<p>box-shadow:
calc(var(--shadow-x) <em> 1px)
calc(var(--shadow-y) </em> 1px)
calc(var(--shadow-blur) * 1px)
rgba(0, 0, 0, var(--shadow-alpha));
}</p>
- 所有偏移/模糊值都用无单位数字存储,便于 JS 动态修改(比如
el.style.setProperty('--shadow-x', '6')) -
* 1px是安全写法:乘以单位不会改变数值,但强制类型转换为<length></length> - 避免写
var(--shadow-x) px—— 这是语法错误,CSS 不允许变量后直接跟标识符
配合 :hover 或 JS 实现动态过渡要小心
CSS 变量本身不可动画,但 box-shadow 属性可以被 transition。关键在于:过渡必须作用在最终生效的属性上,而不是变量本身。
- 给
box-shadow加transition: box-shadow 0.3s ease,不是给变量加 -
:hover中只需修改变量值,浏览器会重新计算box-shadow并触发动画 - 如果用 JS 频繁更新变量(比如跟随鼠标),建议加
will-change: box-shadow防止重排抖动 - 注意 Safari 对
calc()在 transition 中的支持较弱,复杂表达式可能跳帧,优先用简单乘法(var(--x) * 1px)而非除法或嵌套函数
阴影层级和 z-index 的隐性冲突
动态阴影变大时,视觉上卡片“浮起”,但实际 z-index 没变,可能导致遮挡关系错乱——尤其当相邻卡片有不同 z-index 时。
- 阴影是绘制效果,不影响文档流和层叠上下文,
z-index不会随阴影扩大自动提升 - 若需真实层级同步变化,得额外绑定变量到
z-index:比如z-index: calc(10 + var(--shadow-y)); - 但要注意
z-index只接受整数,calc()结果会被截断,所以变量值最好设计为整数步进
真正难的不是算偏移,而是让阴影变化时,交互反馈、层级逻辑和性能表现三者不打架。变量只是杠杆,支点在你怎么把它嵌进整个渲染链路里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











