笔者在开发英语角中添加了比较多的毛玻璃效果,以及后续在开发晨读小程序、新年“奇思妙想”活动中遇到了这种效果,UI 也说后续可能会比较大量的使用这个效果,所以这里记录一下毛玻璃效果的实现以及踩坑记录
使用中的各个场景: 4种实现方式特点以及兼容性对比实现的css名称 | 特点 | 兼容性 |
---|---|---|
filter | 让本层元素以及子元素模糊 | |
backdrop-filter | 让本层元素之下的背景模糊 | |
svg | 只作用到引用了svg滤镜效果的元素 | |
canvas | 可以局部模糊元素 |
兼容性对比:cavas api 、css filter、svg filter兼容性都差不多,backdrop-filter兼容性差点
css滤镜属性值 | 滤镜效果 | 使用值 | 实际效果 |
---|---|---|---|
普通图片 | |||
blur | 高斯模糊 | filter: blur(5px); | |
brightness | 亮度 | filter: brightness(0.4); | |
contrast | 对比度 | filter: contrast(200%); | |
drop-shadow | 阴影 | filter: drop-shadow(16px 16px 20px blue); | |
grayscale | 灰度 | filter: grayscale(50%); | |
hue-rotate | 色相 | filter: hue-rotate(90deg); | |
invert | 反相 | filter: invert(75%); | |
opacity | 透明度 | filter: opacity(25%); | |
saturate | 饱和度 | filter: saturate(30%); | |
sepia | 褐色 | filter: sepia(60%); |
属性介绍:
css滤镜,作用于本层元素以及子元素
具体实现方式:
以英语角活动主题页面为例:
效果如下:
ui解说:
该效果一共有4层,第一层是头图,第二层是蓝色底色,第三层是一个模糊的图片,第四层是文字面板
前端效果实现:
- 头图:
然后绘制一个面板,上移。
面板一共有3层:
-
第一层:背景为纯蓝色
-
第二层:毛玻璃图片:可用:after设置该层,效果用fiter属性实现,让图片模糊,再变暗。
-
第三层:字(不能将字放在第二层,不然字也会模糊)
代码参考:
.panel{
color: rgb(255,255,255);
margin-top:-162px;
background-color: rgb(32,0,77); // 第一层纯色背景
overflow: hidden; // 将第二层超出的图片截断
position: absolute;
border-radius: 20px;
&::before { // 第二层
content:'';
background: url('./assets/headerBg.png') no-repeat center center;
background-size: 375px 442px;
-webkit-filter: blur(50px) brightness(60%);// 设置图片模糊并且变暗
-moz-filter: blur(50px) brightness(60%);
filter: blur(50px) brightness(60%);
position: absolute;
top:0;
top:-280px; // 图片上移,得到想要的背景图片
width: 375px;
height: 442px;
}
.content{ //第三层
position: relative; // 这一层一定要加一个 position:relative 的值
z-index:2; // 同时需要加一个 z-index:2,不然::before的内容会盖在上面
}
}
坑点:
1、在ios中出现lottie卡顿现象
上为以前ios的lottie动效,下为现在ios的lottie动效
解决办法:
- 添加-webkit-transform: translateZ(0px);属性启动硬件加速,无效
2、在iphone x和ipad中出现上下滚动白屏的现象
下面的视频是在ipad中录制的
解决办法:
- 设置html和body的背景色为蓝色,无效
- 网上说添加最外层div添加-webkit-overflow-scrolling: touch;属性可以解决ios滚动不流畅问题,然而无效。
3、出现奇怪的别的颜色
测试时发现在iphone x机型上会必现(左为iphone x,右为正常机型)
backdrop-filter实现方式
超级简单,只需要在需要实现高斯模糊的背景上面的面板上面加上这些参数就好。
background-color: rgba(32,0,77,0.5);
-webkit-backdrop-filter: blur(50px);
backdrop-filter: blur(50px);
只需要在需要模糊的背景之上加上一层半透明的带模糊效果的蒙层即可
坑点:
1、兼容性比较差
解决办法:
- 如果ui接受这个半透明效果也可以
- 如果ui不接受,和ui商量如果不兼容时是否可以让背景是一个纯色
- 通过@support判断浏览器或者移动端页面是否支持这个css属性
/* 默认情况下的样式,如:不支持 backdrop-filter 甚至不支持 @supports 的情况下 应用此效果 */
.element {
background-color: #fff;
}
@supports (-webkit-backdrop-filter: brightness(150%) blur(30px)) or (backdrop-filter: brightness(150%) blur(30px)){
/* 支持 backdrop-filter 时应用的效果,记得把一些属性覆盖掉 */
.element {
background-color: rgba(255, 255, 255, 0.3);
-webkit-backdrop-filter: brightness(150%) blur(30px);
backdrop-filter: brightness(150%) blur(30px);
}
}
2、可能出现白边效果
解决办法:添加overflow: hidden
svg- svg提供filter容器做滤镜效果,它不能直接呈现,可以利用目标SVG元素上的filter属性引用一个滤镜,意思是不能直接出效果,必须引用到目标元素,比如才可以
实现方式:
<svg xmlns="http://www.w3.org/2000/svg"canvas
xmlns:xlink="http://www.w3.org/1999/xlink" class="wh100">
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" />
</filter>
<image filter="url(#blur)" x="0" y="0" width="100%" height="100%" xlink:href="http://p-boe.byted.org/img/ez-data/1611817571717f65d858271~375x0.png" alt="">
</svg>
Canvas中的有个getImageData方法,可以获取每个图片像素点的信息,我们就可以根据特定的算法,对这些信息点进行转化,就能使用各种图片特效。例如,置灰效果,例如反差效果,或者是一些复杂的图像混合效果。
实现方式:
可以使用stackblur-canvas这个包,地址如下:
npm包:https://www.npmjs.com/package/stackblur-canvas[1]
它的参数官网介绍如下:
值得注意的是,它和filter以及svg不太一样,它可以设置模糊的元素的区域
总结css中的backdrop-filter是往往最能够满足ui的需求,比如需要背景中的局部模糊,又得模糊的地方加一下阴影或者圆角,那其他3种实现方式几乎就pass掉了。
而且实现非常简单,有一些坑,但是都可以解决。只是兼容性不如其他3种实现方式,在测试中发现有过一部oppo手机和一部小米手机不支持这个样式。
这个可以和ui协商一下,是否有兜底逻辑或者可以接受半透明效果。如果实在不能接受,并且只是简单的模糊效果,又需要只模糊部分图片,那就可以用cavas做。
如果只是简单的模糊整张图片,则可以考虑用css filter或者svg效果。
参考文档模糊效果的4种实现方案[2]
css技巧[3]
小tip: 使用CSS将图片转换成模糊(毛玻璃)效果[4]
参考资料
模糊效果的4种实现方案: https://zhuanlan.zhihu.com/p/85998526?fileGuid=QW8dgth3kk9XHyt3
❤️ 谢谢支持