深色模式下 box-shadow 应改用浅色系阴影并校准 alpha 值,避免固定黑影发灰;需抽离所有参数为 CSS 变量,严格限定 transition 属性,确保感知重量一致。

box-shadow 颜色写死会导致深色模式下阴影“发灰”或“消失”
直接用 rgba(0, 0, 0, 0.2) 这类固定值定义 box-shadow,在深色背景上会因对比度不足而显得浑浊、边界模糊,甚至视觉上“吃掉”卡片轮廓。这不是渲染 bug,而是颜色空间错配——黑底上投射“半透黑影”,等效于叠加一层灰雾。
- 深色模式下优先改用浅色系阴影:比如
rgba(255, 255, 255, 0.1)或更推荐的color-mix(in srgb, white 15%, transparent) - 避免只靠
blur-radius模拟深度:高 blur + 深色阴影 = 发虚;应同步降低 alpha 值并提升 spread(如从-2px改为-4px)来收紧阴影范围 - 必须显式声明颜色:
box-shadow: 0 4px 8px -2px;是无效写法,浏览器不会自动补默认色,结果不可控
多层阴影叠加时,各层 alpha 值需按深色/浅色分别校准
单层阴影难表现立体感,常用双层:0 2px 4px -1px rgba(...)(主阴影)+ 0 4px 12px -2px rgba(...)(氛围光)。但两层不能共用同一套 alpha,在深色模式下容易叠成一块“脏斑”。
- 浅色模式推荐组合:
0 2px 4px -1px rgba(0,0,0,0.06), 0 4px 12px -2px rgba(0,0,0,0.1) - 深色模式对应调整:
0 2px 4px -1px rgba(255,255,255,0.08), 0 4px 12px -2px rgba(255,255,255,0.12) - 不要用百分比统一缩放 alpha:深色下 0.1 和浅色下 0.1 的视觉权重完全不同,必须实测微调
:root 变量未覆盖全链路是阴影错位的隐藏根源
你以为只改了 --shadow-color 就够?如果 box-shadow 中其他参数(如 spread-radius)仍硬编码,或者伪元素、SVG 图标里的阴影没走变量,就会出现“主体变暗、阴影还亮着”的割裂感。
- 所有可变参数都该抽成变量:
--shadow-offset-y、--shadow-blur、--shadow-spread,哪怕初始值相同 - 第三方组件(如 Vant 的
.van-button)常绕过你的变量作用域,必须用更高优先级选择器重载:html[data-theme="dark"] .van-button - 移动端 Safari 对负
spread-radius渲染异常,若发现阴影边缘锯齿或偏移抖动,临时降级为0并加大blur-radius
transition 写成 all 会放大阴影错觉
用 transition: all 0.3s 后,只要 JS 动态改了任意样式(比如父容器 padding),box-shadow 就会意外触发过渡,造成阴影“自己飘起来”。这种非预期动画会严重干扰用户对卡片层级的判断。
立即学习“前端免费学习笔记(深入)”;
- 严格限定过渡属性:
transition: box-shadow 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 0.3s - 别对
filter: drop-shadow()做过渡——它不走 GPU 加速,iOS 上极易掉帧,阴影会卡顿拖影 - 深色模式切换瞬间的闪屏,本质是变量未在 DOM 构建前就绪,必须用内联 JS 提前读取
window.matchMedia并设data-theme


















