传统的 CSS filter,可以对当前的元素应用指定的滤镜。以模糊(blur)滤镜为例,常常会被拿来实现毛玻璃的效果。然而,因为滤镜只能应用于元素自身,所以毛玻璃的效果也是局限性很大的。一个常见的做法是,背景图片在当前元素中用 background-image 的方式再赋值一次,然后通过定位对齐,再加上 blur 的效果。这样看上去,中间一块的图片就好像有了模糊的效果。
一个例子:
HTML 结构是:
<div class="container">
<div class="filter"></div>
</div>
CSS 是:
.container {
width: 620px;
height: 414px;
background-image: url("../../baseline-jpeg-demo.jpeg");
background-size: 620px 414px;
position: relative;
}
.filter {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 310px;
height: 207px;
background-image: url("../../baseline-jpeg-demo.jpeg");
background-size: 620px 414px;
background-position: -155px -103.5px;
filter: sepia() hue-rotate(120deg);
}
.filter:hover {
filter: blur(10px);
}
然而,显然这样的局限性是很大的。css backdrop filter 就是为了打破这种局限性。有了 css backdrop filter,当前元素的滤镜会加到当前元素下面的所有元素上,而不仅仅是自身的元素。
上面例子的改写(注意:当前浏览器不支持 backdrop-filter 功能):
HTML 保持不变,CSS 改动为:
.filter {
-webkit-backdrop-filter: sepia() hue-rotate(120deg);
}
.filter:hover {
-webkit-backdrop-filter: blur(10px);
}
可以看到,需要加 filter 的部分,没有做额外特殊的处理(比如背景图片的配适),就可以直接使用。简洁明了。
另外,鼠标悬停之后可以看到模糊效果的展示。使用 filter 和使用 backdrop-filter 的展示效果也是略有不同的。主要是,用 filter 这种方案,背后还是有图片的,所以当前景图片模糊之后,边缘部分,后面背景的图片会显示出来,效果有折扣。(如果需要处理,简单的做法是,加大 blur 元素的宽高,然后用 overflow:hidden
把整体显示出来的大小限定回原来需要的大小,这样边缘部分相当于被裁剪了)
当然,css backdrop filter 目前的支持还非常有限。除了 Safari 和 Edge,基本没有浏览器支持。具体可以看 Caniuse。
在 Electron 中,可以通过下面的方法让打开 backdrop-filter 的支持:
new BrowserWindow({
// ...
webPreferences: {
enableBlinkFeatures: 'CSSBackdropFilter',
},
// ...
});
Chrome 对 backdrop filter 的支持进展可以看这个 Issue