对于前端开发来说,CSS 的 box-shadow 属性大家再熟悉不过了。但是有一个 CSS 滤镜 drop-shadow 也可以像 box-shadow 一样,可以输入 x-offset、y-offset、模糊半径和颜色的值来实现类似事情。
.my-element {
filter: drop-shadow(0 0.2rem 0.25rem rgba(0, 0, 0, 0.2));
}
与 box-shadow 不同,它不需要 spread 参数(稍后会详细介绍)。
为什么 drop-shadow 很有用?
如果我们有 box-shadow ,为什么还需要 drop-shadow 呢?
非矩形形状
使用 drop-shadow 可以让我们给一个元素添加阴影,这个阴影并不对应于它的边界框,而是使用该元素的 Alpha 蒙版。例如,我们可以在透明的 PNG 或 SVG 徽标中添加投影。
img {
filter: drop-shadow(0.35rem 0.35rem 0.4rem rgba(0, 0, 0, 0.5));
}
我们可以比较 box-shadow 和 drop-shadow 的效果:

附带说明:过渡和动画 CSS 滤镜的性能并不是特别好,在实际项目中可能最好不要同时制作这么多滤镜的动画。这个例子只是为了好玩!
局限性
如上所述, drop-shadow 不包含 spread 参数。这意味着我们目前无法使用它来创建轮廓效果,我认为这将非常有用。例如,如果它被支持,我们可以使用 drop-shadow 在渐变的背景上创建一个轮廓,就像我们在其他元素上使用 box-shadow 或 text-shadow 一样。
陷阱
即使给定相同的参数, drop-shadow 也无法渲染与 box-shadow 完全相同的阴影效果。我怀疑这与 CSS 过滤器是基于 SVG 过滤器原语有关。无论哪种情况,你都可能需要通过稍微调整 drop-shadow 值来补偿差异。
浏览器支持
所有现代浏览器均支持 CSS 过滤器(包括 drop-shadow)。我倾向于将其作为渐进式增强,而不需要对旧版浏览器进行变通,因为它通常不会对用户体验造成任何重大影响。但如果你确实需要为旧版浏览器提供替代性的样式,你可以使用特性查询来实现,并使用 box-shadow 回退。
.my-element > * {
box-shadow: 0 0.2rem 0.25rem rgba(0, 0, 0, 0.2);
}
@supports (filter: drop-shadow(0 0.2rem 0.25rem rgba(0, 0, 0, 0.2))) {
.my-element {
filter: drop-shadow(0 0.2rem 0.25rem rgba(0, 0, 0, 0.2));
}
.my-element > * {
box-shadow: none;
}
}
总结
虽然drop-shadow有很好的支持,但在实际项目中 drop-shadow 滤镜仍然没有得到充分的利用。我希望通过这篇文章强调了一些使用 box-shadow 的 情况,或许你可以在你的下一个项目中使用它!