最稳妥的做法是用 --elevation-n 存完整 box-shadow 字符串,如 --elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1),兼顾兼容性、可调试性与主题切换可靠性;拆分为多个变量易因缺失或单位错误导致整条阴影失效;深色模式需整套替换而非仅调色;fallback 必须为合法 box-shadow 值;多层及 inset 阴影须存整串字符串。

直接用 --elevation-1 这类语义化变量存完整 box-shadow 字符串,是最可靠、最易维护的方案。拆参数拼接看似灵活,实则极易因语法非法导致整条阴影失效。
为什么不能只拆 --shadow-blur 和 --shadow-color 两个变量
CSS 不支持运行时字符串拼接。box-shadow: var(--shadow-blur) var(--shadow-color) 展开后可能是 8px rgba(0,0,0,.1),这不是合法语法——浏览器要求前四个参数必须是独立值,且顺序固定。一旦某个变量未定义或值格式错(比如 --shadow-blur: 8 漏了 px),整条声明静默丢弃,元素就彻底没阴影。
-
--shadow-blur: 8px✅ 合法单位值 -
--shadow-blur: 8❌ 无单位数值,box-shadow忽略整行 -
--shadow-offset: 0 4px❌ 表面可行,但无法单独调垂直偏移,语义失控
如何正确定义和使用 --elevation-N 变量
所有变量必须挂载在 :root 下,值为完整、合法的 box-shadow 字符串,并带 fallback:
:root {
--elevation-1: 0 1px 2px rgba(0, 0, 0, 0.05);
--elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1);
}
[data-theme="dark"] {
--elevation-1: 0 1px 2px rgba(0, 0, 0, 0.3);
--elevation-2: 0 2px 4px rgba(0, 0, 0, 0.4);
}
- 组件中调用必须用
var(--elevation-2, 0 2px 4px rgba(0,0,0,.1)),fallback 防止 JS 切换主题中途变量未生效 - 深色模式必须用
[data-theme="dark"],@media (prefers-color-scheme: dark)无法响应 JS 主动切换 - 多层阴影要整个字符串存,如
--elevation-3: 0 4px 8px rgba(), 0 8px 16px rgba(),逗号前后空格需统一
JS 动态修改时最容易踩的坑
用 element.style.setProperty('--elevation-2', '0 8px 24px rgba(0,0,0,0.2)') 是安全的,但以下写法会翻车:
- 加引号:
'"0 8px 24px rgba(0,0,0,0.2)"'→ 浏览器当字面字符串,不是阴影值 - 漏单位:
'0 8 24 rgba(0,0,0,0.2)'→ 第三个参数无单位,整条失效 - 在 CSS 里写
box-shadow: var(--elevation-2) !important→!important对自定义属性无意义,还掩盖真实错误 - Safari 上模糊值超过 40px 可能不渲染,动态改大时得加
transform: translateZ(0)触发硬件加速
真正难的是深色模式下阴影不是“换个颜色”就完事——它需要整组参数重调:偏移微增、模糊收窄、alpha 值重算。靠拆分变量去挨个同步,漏一个就错乱;而语义化整串变量,切换时只需重定义那几行,边界清晰,调试时也能在 DevTools 里直接编辑整条阴影值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











