多层box-shadow被遮住因绘制顺序为从左到右、从前到后,首层在最上易压住远层柔光;::before伪元素可补底层投影,需content: ""、absolute定位及relative父容器,偏移+2–4px、模糊24–32px、透明度更低;drop-shadow()不支持inset和spread且圆角边缘失真;ios低电量模式下radial-gradient可能失效,应退化为box-shadow并避免触发硬件加速。

box-shadow多层叠加为什么总被遮住
因为写在同一声明里的多层box-shadow是按**从左到右、从前到后**绘制的:第一个阴影在最上层,最后一个在最底层。但人眼感知“层级感”需要的是**近层锐利+远层弥散**,而默认顺序容易把高对比的近层压在柔光远层上面,结果看起来像糊了一块灰,不是浮起,是“沉底”。真问题不在层数,而在绘制顺序和视觉逻辑错位。
::before伪元素怎么补出真正的底层投影
当box-shadow本身无法表达足够纵深(比如要模拟物体离背景有12px距离,但又不能靠加大blur触发移动端降级),用::before单独画一层远距离投影是最稳的解法。它脱离主元素盒模型,可自由控制z-index、模糊值甚至混合模式。
- 伪元素必须设
content: ""、position: absolute,且父容器需position: relative - 投影偏移量建议比主
box-shadow的offset-y再+2–4px(如主阴影是0 4px,伪元素用0 8px) - 模糊值可大胆设到
24px甚至32px——它不参与主元素渲染管线,iOS Safari不会因此降级 - 透明度务必低于主阴影,例如主层用
rgba(0,0,0,0.12),伪元素用rgba(0,0,0,0.04)
div.card {
position: relative;
box-shadow: 0 2px 6px rgba(0,0,0,0.12);
}
div.card::before {
content: "";
position: absolute;
top: 100%;
left: 0;
width: 100%;
height: 12px;
background: radial-gradient(ellipse at center, rgba(0,0,0,0.04) 0%, transparent 70%);
z-index: -1;
}
为什么不用filter: drop-shadow()替代::before
filter: drop-shadow()确实能生成轮廓贴合的阴影,但它有两个硬伤:drop-shadow()不支持inset,也不接受spread-radius;更关键的是,它会作用于整个元素(含border-radius裁剪后的形状),导致圆角卡片的投影边缘发虚、失真。而::before可以精准控制形状、位置和衰减曲线,适合对质感有要求的场景。
移动端真机测试最容易忽略的一点
伪元素投影在桌面端看着完美,但在iOS Safari低电量模式下可能直接消失——不是CSS失效,而是系统强制禁用了radial-gradient这类渐变渲染。稳妥做法是退化为纯box-shadow:把::before的background换成box-shadow: 0 12px 32px rgba(0,0,0,0.04),并确保该伪元素transform: translateY(0)避免触发硬件加速判断逻辑。复杂感要让步于可用性,这点常被设计稿验收时跳过。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











