用CSS实现一个类似Elementplus的文字虚化效果
我们可能看到过这样的一个效果:页面中的内容滚动穿过某个固定元素时,会产生虚化的视觉效果,能看出文字的轮廓,但是却无法看到具体的内容,给人一种哎呦?不错哦的感觉。
我们来拿element-plus官网作为案例,看看它是如何实现的,然后我们再自己照着实现一版。
比如正常的文字显示是这样的:
正常显示
虚化之后看起来是这个样子:
虚化一下
这个是element-plus官网中首页的效果,顶部有一个固定高度的头部横条,当页面滚动的时候,横条下面的文字就会显示成上面图中虚化后的样子。
首先来分析一下,如果是我们自己实现一个这样的效果,该怎么做呢?看来这个头部横条不能是一个纯白色的背景,因为要能看到文字,所以应该要有一个透明度,但是不能完全透明,因为它看起来不是那么的黑,然后我们观察到有毛玻璃的效果,所以我们要给它模糊一下。
先来做一个最初的原图,在这个基础上尝试几种方案:
原图
从上面的分析中我们可以知道,主要的手段就是:背景+模糊。
我们先来用第一种方案做一下:背景透明度+模糊
效果
它的代码非常简单{ background-color: rgba(255,255,255,0.5); backdrop-filter: blur(4px); }
我们可以通过背景透明度和模糊的程度来调整视觉效果。
其中vite的官网就是这样实现的,只是参数有所改变,我们来看下它的效果和代码:
效果{ backdrop-filter: saturate(50%) blur(8px); background: rgba(255,255,255,.7); }
我们再看elemen-plus官网中的第二种方案:背景图+模糊
效果
它的代码也很简单,我们可以对它简单的分析一下。{ background-image: radial-gradient(transparent 1px,#ffffff 1px); background-size: 4px 4px; backdrop-filter: saturate(50%) blur(4px); }
这里用到了径向渐变,径向渐变默认从中心向外扩散,其中transparent和#ffffff表示从透明过渡到纯白,两个1px的作用就是在1px处直接从透明变为白色,不产生渐变的过渡效果,因此从中心到1px距离处都是透明的,也就是半径为1px的圆内都为透明色,从1px之外都是显示成白色,它这里在实现的时候使用了单位区域4px的大小来绘制背景,然后通过背景重复的方式来平铺整个元素。
可以这样来理解,单位区域内,透明色为半径是1px的圆的范围,那么直径就是2px,为了分布平均,因此左右和上下都加上了1px的纯白,我们来设定一下background-repeat为no-repeat,看一下单位区域的效果,为了明显我们把颜色改一下:
单位区域
这就是单位区域在页面中左上角显示的样子,红色就是原来的透明色,黑色就是原来的白色,为了看得明显,我把页面放大了500%,如果我把背景设置为重复:
背景重复
可以看到就是这个样子,因此它后面的文字就会有一部分通过透明区域显示出来:
显示
这个时候我们再加上模糊效果,那么就会显示成官网中的样子了。
那么还有没有其他的方法呢?
有!思路跟第二种类似,只不过我们不用径向渐变,而是使用线性渐变。
我们可以看到,径向渐变有误伤的像素,4px的大小会覆盖两个像素点,使我们看不见后面的文字,而且圆形不能使文字完全露出来。
最好是一个像素看不见,一个像素能看见,这样就像蒙了一层纱布一样均匀。
要想实现这样的效果,我们首先把单位区域设置成2px大小的正方形,然后借鉴一下CSS3 Patterns Gallary 的鬼斧神工:
单位区域
我们通过设置透明色和黑色来展示样子,同样页面放大了500%。代码如下:{ background-image: linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%, black), linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%, black); background-size: 2px 2px; background-position: 0 0, 1px 1px; }
我们再把背景重复一下:
背景重复
这样就变成了一个透明像素一个黑色像素。我们把黑色变成白色再看实际的文字显示:
效果
可以看到,文字就好像每隔一个像素点都被掏空了一样。
然后我们再加上之前用到的模糊,调整一下视觉效果:
效果
这样就有了毛玻璃叠加纱布的视觉效果。完整代码如下:{ background-image: linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%, black), linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%, black); background-size: 2px 2px; background-position: 0 0, 1px 1px; backdrop-filter: blur(4px); }
原理不难,技术也是很简单,都是一些好玩的css特性,实现的方式也很多。
创造力是无穷的,就看谁的花样多!