css backdrop filter

CSS

传统的 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