# css毛玻璃效果实现

# 背景概述

公司的 UI 最近比较喜欢用毛玻璃的效果来虚化背景突出文字, 比如下图这种效果

# 实操

# backdrop-filter

首先看一下MDN (opens new window)

backdrop-filter

backdrop-filter 属性可以让你为一个元素后面区域添加图形效果(如模糊或颜色偏移). 因为它适用于元素背后的所有元素, 为了看到效果, 必须使元素或其背景至少部分透明.

从描述看这个属性就非常适合我们用来做毛玻璃效果, 我们直接写一个简单的demo (opens new window)尝试一下

效果也挺完美的, 看起来我们的需求就很简单的实现了.那么我们再来看一下兼容性:

这个属性的兼容性并不好, 所以并不适合用在C端

# blur

一开始是参考了这篇文章 (opens new window)

通过这种方式确实也可以实现比较好的毛玻璃效果, 首先说一下大体思路.

blur属性会作用在整个div上, 所以如果我们单纯的给一个div加上blur, 会带着上面的文字一起blur掉.那么接下来的思路就清晰了, 我们用两层, 一层是正常的图片, 一层是blur的图片, 通过叠加的方式显示毛玻璃效果.

首先我们需要把两张图片的红框部分加起来, 就能显示一个部分模糊的毛玻璃效果, 最后再盖一个div在模糊部分上方显示我们需要显示的内容, 就能实现我们的毛玻璃效果.

我们可以参照这篇文章里面的实现, 但是这里面的实现用到了这个:

background-position: center top;
background-size: cover;
background-attachment: fixed;

这些其实就是用来定位两张图片属性, fixed这个属性是相当于视窗的, 显然我们的需求是相当于某个div需要定位两张图片, 所以这里我们不能用上文的方式来实现我们的需求, 需要我们自己用另一种方式去定位两张图片.

首先把第一张图片给裁剪到我们需要的高度, 需要注意的是这里要修改图片的初始位置, 这样才能显示出来的内容才是下半部分的内容.

.img {
  position: relative;
  
  filter: blur(10px);
  background: url("https://i.postimg.cc/DzgQGyhx/image.png") left bottom/375px 280px no-repeat;
  width: 375px;
  height: 120px;
}

这样就能达到这个效果

我们再把这个覆盖到原图上面去, 定位到最下面, 再将内容也覆盖到原图上, 定位到最下面, 就能实现毛玻璃效果 (opens new window)

# image-mask

上述切出图片的下半部分是通过改变heightbackground-position实现的, 其实也可以用image-mask去实现.

.img {
  width: 375px;
  height: 280px;
  background: url("https://i.postimg.cc/DzgQGyhx/image.png") center
    center/375px 280px no-repeat;
  filter: blur(20px);
  mask-image: linear-gradient(to bottom, transparent 57%, green 0);
  -webkit-mask-image: linear-gradient(to bottom, transparent 57%, green 0);
}

通过这段css就能截取出一张图的下半部分, 再将它定位到图片下方, 就能实现毛玻璃 (opens new window)的效果

其中 mask-image 的兼容性也还是不错的

# 细节优化

可能大家能注意到第二种和第三种方法边缘处的模糊效果并不是很好, 元素的边缘模糊效果减弱了, 所以我们需要想办法将边缘扩大. 举一个第三种方法的例子, 将高度增加, 修改linear-gradient的比例, 就能将需要模糊的图片底部距离增加. 优化代码 (opens new window)

这样看起来的效果就好多了.