说一说能让你的网页~Bling~Bling~的东西 —— 滤镜(CSS3)


2020年4月4日清明节,全国范围内举行了哀悼活动。当天,互联网上很多国内网站的首页也都由彩色变成了黑白色。在此,我们来探讨一下如何使用前端来一秒实现网站变黑白。即:不借助包括但不限于JavaScript在内的任何脚本语句,给网页加特效。例如,让网页变为灰色。

源代码

css/backdrop_filter.html

直接上代码

就一行CSS:

body{
    filter: grayscale(1)
}

多简单啊,需求完成,本文结束~

???

你这是标题党吗?不就是网页变黑白吗?哪里BlingBling了?

行吧,为了满足广大吃瓜群众(虽然截至发稿时,本人在本文的首发平台Github上并没有多少Followers)的求知欲,我就又继续多看了几眼CSS滤镜相关的内容。

何谓“滤镜”

滤镜,英文“filter”,中文又可译为“过滤器”。

摄影中的滤镜

在摄影时,有时为了达到某种效果,会在镜头前添加一些镜片。

  • 我们用相机拍摄蓝天,但天有时太白,不够蓝,于是我们可以在镜头前添加一片带有蓝色的镜片,实现蓝天的效果;
  • 夜里拍摄路灯,希望路灯光源能够产生光芒,这时我们可以在镜头前增加一个星光镜来实现效果;
  • 拍摄瀑布或是河流的时候,我们希望水流能够连贯,产生类似“涓涓细流”的效果,这时候我们或许会使用长曝光来拍摄,但若白天长曝光可能会导致画面一片白色(过曝),这是我们可以在镜头前增加一个减光镜来防止在长时间曝光时曝光过度。

以上说的蓝色镜片、星光镜以及减光镜即是滤镜。

设计中的滤镜

很多时候,我们所拍摄/渲染/设计的原片不能够直接用于生产,需要进行一些后期处理。后期处理自然就离不开各种设计软件,例如Adobe家的Photoshop、illustrator、Premiere、After Effects以及Flash。这些软件都离不开滤镜这个概念。

AE滤镜菜单
PS滤镜菜单

CSS3 Filter

通过上文,我们了解到,滤镜就是一种能够对原始图像添加各种效果的东西。接下来我们就来看一看网页中的滤镜 —— CSS3 Filter。

目前,较新版本的浏览器已经能够支持CSS3滤镜属性:filter ,该属性用于为所选中的元素添加滤镜效果。

此外,如果你使用的是最新版本的Chrome浏览器(76+),你甚至还可以使用 backdrop-filter 属性,该属性用于为所选中元素后方的内容添加滤镜效果。

其属性值包括以下几个:

  • blur(npx)
    模糊滤镜,为当前元素设置模糊效果。似乎在制作毛玻璃效果时会十分有用。
    n为>0的数值;单位不能为空,必须是具体的尺寸单位,不支持百分比。
  • brightness(n)
    亮度滤镜,为当前元素设置亮度。比如可以让一个元素更亮/更暗一些。
    n为>0数值,无单位,或使用百分比来表示,1或100%表示亮度无变化;值越大元素越亮,直到不能再亮;值越小则画面越趋向于全黑。
  • contrast(n)
    对比度滤镜,为当前元素设置对比度。比如可以让一个元素内容对比度更强/更弱一些。
    n为>0的数值,无单位,或使用百分比来表示,1或100%表示对比度无变化;值越大元素对比越强烈,直到不能再亮;值越小则画面越趋向于灰色。
  • grayscale(n)
    灰度滤镜,设置元素的去色程度,即把元素中包含的颜色去除。
    n为>0的数值,无单位,或使用百分比来表示;值越小,去色程度越低,为0时相当于无效果;值越大,去色程度越高,>=1时元素则完全去色(似乎只保留亮度信息),相当于PS中的去色(Shift+Ctrl+U)效果
  • invert(n)
    反色滤镜,即将元素中的颜色信息进行反转。
    n为>0的数值,无单位,或使用百分比来表示;值越小,反色程度越低,为0时相当于无效果;值越大,反色程度越高,为>=1时元素则完全反色,相当于PS中的反相(Ctrl+I)效果;为0.5时,元素似乎完全变灰,类似contrast(0)。
  • opacity(n)
    透明滤镜,即设置元素不透明度,和CSS opacity大致相同?
    n为>0的数值,无单位,或使用百分比来表示;值越小,不透明度越低,为>=1时相当于无效果,为0时完全透明。
  • saturate(n)
    饱和度滤镜,即改变元素中的颜色的饱和度。
    n为>0 的数值,无单位,或使用百分比来表示;为0时完全灰度,为1时相当于无效果;大于1后,值越大颜色越鲜艳,直到颜色溢出。
  • sepia(n) – 褐色滤镜
    褐色滤镜,设置元素的褐色程度,制造出一种类似变黄纸片/老旧照片的效果。
    n为>0的数值,无单位,或使用百分比来表示;值越小,褐色程度越低,为0时相当于无效果;值越大,褐色程度越高,>=1时元素则完全只剩下褐色(似乎只保留亮度信息)。
  • drop-shadow(apx, bpx, cpx, color)
    投影滤镜,即根据元素形状,设置投影效果。
    a, b, c分别表示阴影的水平偏移、垂直偏移、模糊偏移,单位不能为空,必须是具体的尺寸单位,不支持百分比;color表示投影的颜色。
    设置方式和CSS box-shadow大致相似。区别在于:
    1. box-shadow仅能够为box设置阴影,而box必然是方形(或border-radius加了圆角的方形),而drop-shadow滤镜在添加阴影时能够考虑物体的形状,包括文字、SVG、PNG图像Alpha通道等等;
    2. box-shadow属性值包括6个,按照顺序大致为阴影的水平偏移、垂直偏移、模糊偏移、扩散程度、颜色、以及阴影投影位置(默认为空时在外部投影,设置inset时为在内部投影),但drop-shadow滤镜仅支持水平偏移、垂直偏移、模糊偏移、颜色。
  • hue-rotate(ndeg)
    色相旋转滤镜,即对元素的色相进行旋转。(色相的相关内容可参阅https://github.com/gogoend/gogoend.github.io/issues/11 )
    n为数值,单位常用角度(deg),除此之外还可以用圈数(turn)、弧度(rad),以及刚刚笔者百度到的梯度(grad)。

经过测试,以上所有滤镜都可以使用 CSS3 动画/过度


  • url(svg-url)
    该属性可用于从外部引入一个SVG滤镜来作用到当前元素上。svg-url表示包含滤镜的SVG文件的路径。滤镜在SVG文件中以id命名,在url中以#id来访问。
    笔者认为上面的很多滤镜都可以基于SVG滤镜来实现。如果你有使用过illustrator这款绘制矢量图的软件,可发现其包含了很多预置的使用SVG实现的滤镜。
    image
    我们可以直接查看其代码,如图所示。
    image
    SVG滤镜内容很多,对于细节,我将另开一篇博文进行介绍。

滤镜的兼容性

还是回到我们本文的需求,参考自:

将页面变灰 – 司徒正美 – 博客园
(R.I.P. 想不到是在你离世后我才发现你的博客)

小tip: 使用CSS将图片转换成黑白(灰色、置灰)

虽然兼容性目前已经不再是个问题,目前地球上的设备所使用的浏览器几乎都是以Chromium为内核的浏览器,当前最新版本浏览器的确仅需类似上方这样一行代码即可实现黑白页面。但兼容性问题作为各种浏览器前辈留给我们的遗产,也是值得一看的。

参考自司徒正美与张鑫旭两位大佬的博客,前缀写法可以让滤镜支持早期浏览器。

html {
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);
    -moz-filter: grayscale(100%);
    -ms-filter: grayscale(100%);
    -o-filter: grayscale(100%);
    filter: url(desaturate.svg#grayscale);
    filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
    -webkit-filter: grayscale(1);
}
<!-- desaturate.svg -->
<svg&nbsp;version="1.1" xmlns="http://www.w3.org/2000/svg">
    <filter&nbsp;id="grayscale">
        <feColorMatrix&nbsp;type="matrix" values="
0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0.3333 0.3333 0.3333 0 0
0      0      0      1 0
        ">
        </feColorMatrix>
    </filter>
</svg>

结个尾

以上就是有关CSS滤镜的相关内容,准确来说,应该是CSS3滤镜的相关内容。事实上,早期版本的IE浏览器就包含有滤镜,但并不符合标准,不能够在其它浏览器间通用。标准中的CSS滤镜直到CSS3发布时才有。

曾记得我两年多前一个人在教室里捣鼓前端,就发现了浏览器里滤镜这个宝藏。那天我试着将一个黑色半透明div放在了使用了模糊滤镜的body之上,产生了一种类似Win7毛玻璃的效果,顿时,我被浏览器所提供的这种能力给震惊到了,“天哪,浏览器怎么还能做出和Ae/Ps模糊的效果!”这大概就是我走上前端这条不归路的原因吧。

其实我还想再写写SVG滤镜的相关内容,也就是上文所提到的filter: url(svg-url)属性,无奈这一块内容真的有点多,近期有点小忙,等稍闲下来的时候,另写一篇博客慢慢写吧。


评论