最可靠方式是分别在 :root 和 @media (prefers-color-scheme: dark) 中定义阴影变量。scss 函数无法响应系统偏好变化,必须依赖原生媒体查询;深色模式需改颜色和透明度,如用 rgba(255,255,255,0.08),而非仅调 alpha。

直接在 :root 和 @media (prefers-color-scheme: dark) 里分别定义同一组阴影变量,是最可靠、最易维护的方式。 不要用函数动态生成暗色阴影值,也不依赖 JS 切换主题类——CSS 变量 + 媒体查询原生支持、零运行时开销、深色模式切换即时生效。
为什么不能靠 SCSS 函数生成暗色阴影
SCSS 是编译时语言,@function shadow-for-dark() 输出的只是固定值,无法响应用户系统偏好实时变化。即使你写 @if $dark-mode { ... },那个 $dark-mode 也是编译期变量,不是运行时信号。结果就是:用户开了深色模式,页面仍显示浅色阴影,除非你手动重建整个 CSS 文件。
- 所有“自动”都得靠浏览器原生机制,
@media (prefers-color-scheme: dark)是唯一被广泛支持的标准 - 用
dark:前缀(如 Tailwind)本质也是靠这个媒体查询生成对应规则,不是魔法 - 试图在 SCSS 里用
lighten()或rgba(0,0,0,0.1)算出“适配深色的阴影”,反而会得到发灰、不可见或过重的效果
如何正确定义可切换的阴影变量
把阴影值抽成语义化变量,在亮/暗两套作用域中分别赋值。关键点是:深色模式下必须改颜色和透明度,不能只调 alpha。
- 浅色模式用
rgba(0, 0, 0, 0.08)、rgba(0, 0, 0, 0.12)这类低透明黑 - 深色模式必须换为高亮色+低透明,例如
rgba(255, 255, 255, 0.08)或hsla(0, 0%, 100%, 0.06),否则阴影糊成一片 - 变量名带单位且完整,比如
$shadow-card: "0px 2px 4px rgba(0,0,0,0.12), 0px 1px 2px rgba(0,0,0,0.24)";—— 注意引号,这是给unquote()准备的 - 最终注入 CSS 时,用
box-shadow: unquote($shadow-card);,否则引号残留导致整条失效
多层阴影在深色模式下的常见失效点
深色模式下,单层阴影容易“消失”,多层反而更可控——但必须重新校准每层的颜色与透明度比例,不能简单复制浅色参数。
- 第一层(近层微影):浅色用
rgba(0,0,0,0.05),深色建议rgba(255,255,255,0.04),偏移和模糊保持一致 - 第二层(主体浮起):浅色常用
rgba(0,0,0,0.1),深色改用rgba(255,255,255,0.08),避免压暗背景 - 第三层(远层氛围):浅色可能用
rgba(0,0,0,0.15),深色请降为rgba(255,255,255,0.06),否则边缘泛白 - 绝对禁止在变量里写
inset或!important—— 它们属于使用上下文,应留在选择器里控制
真正容易被忽略的,是阴影颜色与背景的相对关系:深色模式下,阴影不是“变暗”,而是“提亮+降饱和”。用纯黑或纯白都不对,必须让 rgba 的 R/G/B 分量贴近背景主色,alpha 值比浅色模式再低 0.02–0.04 才自然。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











