box-shadow 不支持渐变色,因其只接受 color 类型而非 image 类型的 linear-gradient();实现渐变阴影需用伪元素+linear-gradient+filter:blur()、drop-shadow()(依赖 alpha 通道)或多层 box-shadow 叠加。

box-shadow 本身不支持渐变色,直接写 linear-gradient() 会静默失效——这不是你写错了,是 CSS 渲染机制决定的。真要实现“渐变阴影”效果,得绕开 box-shadow 的限制,用更底层的手段模拟。
为什么 box-shadow: ... linear-gradient() 不生效
CSS 的 box-shadow 接收的是单一颜色值(color 类型),而 linear-gradient() 返回的是 image 类型。浏览器在解析时发现类型不匹配,直接丢弃整条声明,不会报错,也不会 fallback。这是最常被误以为“语法错误”的兼容性陷阱。
常见错误现象:
- 写了
box-shadow: 0 4px 12px linear-gradient(to bottom, #0004, transparent);,结果阴影完全消失 - 开发者反复检查拼写、括号、分号,却忽略类型系统这一层
伪元素 + linear-gradient + filter: blur() 是最可控方案
这个组合能精确控制渐变方向、模糊强度、扩散范围和透明度衰减,适合生产环境。
实操要点:
- 给目标元素设
position: relative - 用
::before或::after创建伪元素,content: "",position: absolute - 伪元素尺寸略大于主元素(如
width: calc(100% + 16px),height: 24px),并偏移到底部:bottom: -12px,left: -8px - 背景用
background: linear-gradient(to bottom, transparent, rgba(0,0,0,0.3), transparent),确保两端透明,中间有浓度峰值 - 加
filter: blur(6px)(不宜超过 10px,否则边缘糊成一片)和z-index: -1
示例关键片段:
.card {
position: relative;
}
.card::before {
content: "";
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
width: calc(100% + 16px);
height: 24px;
background: linear-gradient(to bottom, transparent, rgba(0,0,0,0.3), transparent);
filter: blur(6px);
z-index: -1;
}
filter: drop-shadow() 只对 Alpha 通道起作用
它不是“给颜色加阴影”,而是“按元素透明轮廓投射纯色阴影”。所以它能做出贴合圆角、clip-path 或 SVG 形状的阴影,但无法控制阴影内部的色彩过渡。
使用前提:
- 元素本身要有透明区域(比如
background: radial-gradient(circle at center, #fff, transparent 70%)) - 或配合
mask/clip-path切出非矩形形状 - 不能用在纯不透明矩形上——那样和
box-shadow效果一致,还多一层渲染开销 - Safari 15.4 之前版本对
drop-shadow()的模糊半径支持不稳定
多层 box-shadow 叠加只是视觉错觉
适合轻量场景(比如按钮悬停微动效),但本质仍是多个纯色阴影堆叠,不是真正渐变。
参数设计建议:
- 从浅到深,用 3–4 层:例如
box-shadow: 0 1px 2px rgba(0,0,0,0.05), 0 2px 4px rgba(0,0,0,0.1), 0 4px 8px rgba(0,0,0,0.15) - 每层垂直偏移递增,模糊半径同步放大,避免出现“断层感”
- 别超过 5 层,否则重绘压力明显上升,尤其在滚动区域
真正难的不是写出代码,而是判断该用哪种方案:伪元素方案要手动调位置和尺寸;drop-shadow() 依赖图形本身的 Alpha;多层 box-shadow 看似简单,但颜色过渡生硬。选错方案,后期改起来比重写还费劲。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











