box-shadow 的 z-index 无效,需通过多层阴影参数与堆叠上下文协同模拟景深;SCSS 循环可精准控制距离、模糊、透明度衰减;避免 overflow: hidden 和半透明背景破坏立体感。

Box-shadow 的 z-index 无效,得靠层叠顺序和阴影参数协同控制
CSS 中 box-shadow 本身不产生真实 Z 轴空间,它只是绘制在元素“上方”的视觉投影。所谓“景深感”,本质是模拟人眼对远近物体模糊度、大小、明暗的感知差异——这必须靠多层 box-shadow 配合元素自身的堆叠上下文(stacking context)来实现,而不是依赖 z-index 数值本身。
- 单个
box-shadow只能表达“一层投影”,要模拟空气透视或距离衰减,至少需 2–3 层:近处清晰锐利、远处弥散微弱 - 父容器若未触发新 stacking context(如设置
transform、opacity、will-change等),子元素的阴影会统一绘制在父级所在层,无法形成层级穿透感 - 阴影的
blur值不是越大越“远”——过大的模糊会丢失方向感;通常搭配小偏移(0 2px)+ 低透明度 + 多层递增 blur 才显自然
SCSS 中用循环生成多层 box-shadow 更可控
手写 4–5 层 box-shadow 容易出错且难维护,SCSS 的 @for 或 @each 能把“距离→偏移→模糊→透明度”的映射逻辑显式化。关键是定义好物理隐喻:比如第 1 层代表距表面 2px,第 3 层代表 12px,而非随意递增。
@function depth-shadow($layers: 3) {
$shadows: ();
@for $i from 1 through $layers {
$distance: $i * 2px; // 线性增长距离
$blur: $i * 4px;
$alpha: 0.08 - ($i * 0.02); // 逐层衰减透明度
$shadow: 0 $distance $blur rgba(0, 0, 0, $alpha);
$shadows: append($shadows, $shadow, comma);
}
@return $shadows;
}
<p>.card {
box-shadow: depth-shadow(4); // 生成 4 层
}- 避免用
random()控制参数——景深需要可预测的衰减曲线,否则 UI 显得随机而不稳定 - 若需支持深色模式,别在函数里硬编码颜色,改用
var(--shadow-color)并在 :root 中定义 - 编译后 CSS 仍为单条
box-shadow声明,浏览器兼容性与手动书写一致(IE10+ 支持多层)
真实场景中常被忽略的两个破坏景深的因素
即使阴影参数完美,以下两点会直接让“立体感”塌陷:
-
overflow: hidden在父容器上会裁剪掉所有超出边界的阴影——景深依赖阴影外溢来暗示“背后还有空间”,务必检查父级是否意外截断 - 元素自身
background用了半透明(如rgba(255,255,255,0.8)),会导致多层阴影叠加后发灰、发浑,失去层次对比;优先用纯色背景 + 独立伪元素模拟毛玻璃,或改用backdrop-filter
移动端高 DPR 下阴影性能比你想象中更敏感
在 iPhone 或高端安卓机上,box-shadow 的 blur 渲染由 GPU 完成,但过大的 blur(如 >24px)或过多层数(>5)会触发离屏渲染(offscreen render),造成滚动卡顿。实测发现:
立即学习“前端免费学习笔记(深入)”;
- 3 层阴影(
0 2px 4px,0 4px 12px,0 8px 24px)在 iOS Safari 中帧率稳定 - 把最后一层的
24pxblur 换成32px,同等机型下 60fps 掉落至 42fps - 用
will-change: transform对阴影无加速作用;真正有效的是减少 blur 半径,或用filter: drop-shadow()替代(但后者不支持内阴影且无法多层叠加)
景深不是参数堆砌的结果,而是对视觉权重、设备能力、上下文约束的综合权衡——调参前先问:这个阴影,用户真的需要感知到“12px 远”吗?


















