学习CSS3 filter滤镜 drop-shadow方法
对于前端开发来说,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
的效果:
使用 box-shadow
为我们提供了一个矩形阴影,即使元素没有背景,而 drop-shadow
则为图像的非透明部分创建阴影。
无论图像是内联在 HTML 中(作为内联 SVG,还是在 <img>
标签中)或 CSS 背景图像,这都将起作用,这意味着我们还可以为渐变背景添加阴影。这些形状是通过背景渐变创建的,并应用了 drop-shadow
滤镜:
HTML 代码:
<div class="grad"></div> <div class="grad"></div> <div class="grad"></div>
CSS 代码:
.grad { width: 15rem; height: 15rem; margin: 1rem; background: linear-gradient(45deg, deeppink 50%, transparent 50%); filter: drop-shadow(0.6rem 0.6rem 1rem rgba(20, 20, 180, 0.8)); } .grad:nth-child(2) { background: radial-gradient(circle at center, deeppink 50%, transparent 50%); } .grad:nth-child(3) { background: linear-gradient(45deg, transparent 60%, deeppink 60%), linear-gradient(135deg, transparent 60%, deeppink 60%); }
效果如下:
剪裁元素
如果我们使用 clip-path
或 mask-image
修剪或遮罩元素,则我们添加的任何 box-shadow
也会被修剪——因此,如果它在修剪区域之外,则将不可见。
但我们可以通过在元素的父元素上应用 drop-shadow
滤镜,在剪切的元素上创建一个阴影。
HTML 代码:
<div class="parent-element"> <div class="clipped-element"></div> </div>
CSS 代码:
* { box-sizing: border-box; } body { margin: 0; padding: 3rem; min-height: 100vh; display: flex; align-items: center; justify-content: center; } .parent-element { filter: drop-shadow(0.4rem 0.4rem 1rem rgba(0,30,200,0.8)); } .clipped-element { width: 20rem; height: 20rem; margin: 0 auto; background-color: deeppink; clip-path: polygon(0 0,50% 0,100% 50%,50% 100%,0 100%,50% 50%); }
效果如下:
分组元素
有时候,我需要构建由重叠元素组成的组件,这本身就需要投射阴影。
如果我们在整个组件上添加 box-shadow
,则会留下奇怪的空白区域:
如果我们给每个元素单独添加一个 box-shadow
,那么每个元素都会投下自己的阴影,这可能不是我们想要的效果。我们需要采用一些巧妙的 CSS 来隐藏那些元素重叠的阴影。
但是通过在整个组件上使用 drop-shadow
,我们可以准确地在我们想要的地方得到阴影,而不需要求助于奇技淫巧。
完整代码:点击这里
多重投射阴影
这是一件有趣的事情:你可以使用多个阴影以获得一些很酷的效果!查看以下演示。
HTML 代码:
<div class="parent-element"> <div class="clipped-element"></div> </div>
CSS 代码:
.parent-element { filter: drop-shadow(10rem 0 0 rgba(0, 30, 200, 0.8)) drop-shadow(-10rem 0 0 rgba(0, 30, 200, 0.8)) drop-shadow(20rem 0 0 rgba(0, 30, 200, 0.8)) drop-shadow(-20rem 0 0 rgba(0, 30, 200, 0.8)); transition: filter 600ms; } .parent-element:hover { filter: drop-shadow(0 0 0 rgba(0, 30, 200, 0.8)); } .clipped-element { width: 20rem; height: 20rem; margin: 0 auto; background-color: deeppink; clip-path: polygon(0 0, 50% 0, 100% 50%, 50% 100%, 0 100%, 50% 50%) }
效果如下:
附带说明:过渡和动画 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 的
情况,或许你可以在你的下一个项目中使用它!
码云笔记 » 学习CSS3 filter滤镜 drop-shadow方法