序
某日,逛一个技术网站,被它的弹窗吸引,它所实现的效果类似于iOS系统里面的系统弹窗,但是我觉得这不够美,不够纯净。
上面的图片虽然有毛玻璃效果,但是总觉得不那么完美,我想要的是纯净的毛玻璃,没有杂色的。
无关设计美感,只是自己更希望实现第二种的纯粹效果。
应用场景
其实,毛玻璃背景多是为了突出显示部分,提升系统美感。比较常用的应用场景是诸如弹框或者引用等部分。
常见实现
最常见几种实现无非以下几种
- rgba()作为背景颜色
- 透明png图片用图像处理工具做出高斯模糊效果,作为元素背景
- CSS的滤镜blur()
第一种方式最为简单,实现出来的效果如下,没有模糊不怎么好。
第二种方式对开发人员来说,为了兼顾兼容性和美感,是比较好的方式,实现的效果也和预期最佳没有区别,但是会额外增加一个网络请求,可以截取一个1x1像素小块,然后用background-repeat实现。
第三种方式我们先看看实现方式再辩优劣。
基于CSS filter: blur()的实现
首先我们构建基本结构,我构建的结构如下:
<div class="img-wrapper">
<div class="inner">
<p>1.给web应用添加struts2和Spring支持
2.在web.xml文件中添加Spring上下文,用以将Struts Action处理器交至Spring托管
Web.xml配置如下</p>
</div>
</div>
.img-wrapper
是最外层元素,我们要实现的毛玻璃弹窗显示位置位于该元素之上。.inner
是弹窗的包裹元素,p
是弹窗内容,首先我们布局好底层背景以及透明弹窗,样式如下:
body {
margin: 0;
}
.img-wrapper {
margin: 0 auto;
width: 600px;
height: 800px;
background: url('./img/test.jpg') no-repeat;
color: white;
padding: 1px;
background-size: 600px auto;
}
.inner {
position: relative;
padding: 50px;
margin: 200px auto;
width: 300px;
height: 100px;
box-shadow: -2px 4px 20px 2px black;
}
现在尝试给弹框添加滤镜:
.inner {
***
filter: blur(5px);
}
完全不是我们想要的效果,
.inner
内部的所有内容都被模糊了,因此滤镜不能作用在.inner
的内容部分,很容易想到运用伪元素添加一个蒙层,样式如下:
.inner::before {
content: '';
position: absolute;
margin: -40px;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('./img/test.jpg') no-repeat;
background-size: 600px auto;
background-position: -60px -160px;
filter: blur(5px);
}
伪元素作为蒙层挡住了内容,需要用`z-inde来调整叠放层次:
.inner {
***
z-index: 0;
}
.inner::before {
***
z-index: -1;
}
这样调整后就可以实现预期的效果
几点注意
-
blur在作用区域边缘有消散现象,因此需要将伪元素的宽高都设置大一些(负margin值),一般20px到30px即可,然后将伪元素父元素的overflow设置为hidden;
伪元素作为蒙层,其背景图的大小和位置要与背景元素保持一致,因此需要将伪元素本身的background-position调整,用负值调整其背景图位置;
由于背景图片的位置限制,一般的弹出框
.inner
相对image-wrapper
的位置应是固定的,对于不固定位置的弹出框或显示层,应该同时调整.inner
的位置,比如,弹出框水平右移200px,那么其背景应该水平向左移动200px,比较麻烦;
总结
最理想的效果如果是最麻烦的,要么是实现方式有问题,要么是技术有待升级。
-- Kai Zou
的确,我们现在看来,最好的效果,可能实现起来比较麻烦,但是,从这个过程中我们知道了一些解决问题的有趣的思路。技术有限,如有疏漏之处,敬请批评指正。本节是我读LEA VEROU姐的《CSS secrets》后根据自己的理解所作。
FLAG
用MARKDOWN作文还是有点不习惯,但是确实很好用。另外,知识必须要花费大量的时间才能为己所用。