✨让网页 Bling-Bling 的CSS滤镜

793 阅读9分钟

2020年4月4日,清明节,全国范围内举行了哀悼活动。当天,互联网上很多国内网站的首页也都由彩色变成了黑白色。在此,我们来探讨一下如何使用前端来一秒实现网站变黑白。

源代码

css/backdrop_filter.html

直接上代码

一行CSS:

body{
    filter: grayscale(1)
}

So easy,本文结束~

???

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

行吧,为了满足广大吃瓜群众以及笔者自己的求知欲,我就又继续多看了几眼CSS滤镜相关的内容。

何谓“滤镜”

滤镜,英文“filter”。

摄影师眼中的滤镜

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

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

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

设计师眼中的滤镜

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

AE滤镜菜单

PS滤镜菜单

CSS3 Filter

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

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

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

现在就来逐个介绍一下它们,同时我们也可以看到它们都附带了一个示例。

所有示例使用下图作为原图来演示

image.png

示例图截取自开源电影 Big Buck Bunny

  • blur(npx) 模糊滤镜,为当前元素设置模糊效果。似乎在制作毛玻璃效果时会十分有用。 n为>0的数值;单位不能为空,必须是具体的尺寸单位,不支持百分比。

    .blur {
            filter: blur(2px);
    }
    

    image.png

  • brightness(n) 亮度滤镜,为当前元素设置亮度。比如可以让一个元素更亮/更暗一些。 n为>0数值,无单位,或使用百分比来表示,1或100%表示亮度无变化;值越大元素越亮,直到不能再亮;值越小则画面越趋向于全黑。

    .brightness {
        filter: brightness(1.5);
    }
    

    image.png

  • contrast(n) 对比度滤镜,为当前元素设置对比度。比如可以让一个元素内容对比度更强/更弱一些。 n为>0的数值,无单位,或使用百分比来表示,1或100%表示对比度无变化;值越大元素对比越强烈,直到不能再亮;值越小则画面越趋向于灰色。

    .contrast {
        filter: contrast(2);
    }
    

    image.png

  • grayscale(n) 灰度滤镜,设置元素的去色程度,即把元素中包含的颜色去除。 n为>0的数值,无单位,或使用百分比来表示;值越小,去色程度越低,为0时相当于无效果;值越大,去色程度越高,>=1时元素则完全去色(似乎只保留亮度信息),相当于PS中的去色(Shift+Ctrl+U)效果

    .grayscale {
        filter: grayscale(1);
    }
    

    image.png

  • invert(n) 反色滤镜,即将元素中的颜色信息进行反转。 n为>0的数值,无单位,或使用百分比来表示;值越小,反色程度越低,为0时相当于无效果;值越大,反色程度越高,为>=1时元素则完全反色,相当于PS中的反相(Ctrl+I)效果;为0.5时,元素似乎完全变灰,类似contrast(0)。值的注意的是,invert滤镜很容易和revert关键字互相混淆。这里一定要注意哦~

    .invert {
        filter: invert(1);
    }
    

    image.png

  • opacity(n) 透明滤镜,即设置元素不透明度,和CSS opacity大致相同? n为>0的数值,无单位,或使用百分比来表示;值越小,不透明度越低,为>=1时相当于无效果,为0时完全透明。

    .opacity {
        filter: opacity(0.3);
    }
    

    image.png

  • saturate(n) 饱和度滤镜,即改变元素中的颜色的饱和度。 n为>0 的数值,无单位,或使用百分比来表示;为0时完全灰度,为1时相当于无效果;大于1后,值越大颜色越鲜艳,直到颜色溢出。

    .saturate {
        filter: saturate(4);
    }
    

    image.png

  • sepia(n) - 褐色滤镜 褐色滤镜,设置元素的褐色程度,制造出一种类似变黄纸片/老旧照片的效果。 n为>0的数值,无单位,或使用百分比来表示;值越小,褐色程度越低,为0时相当于无效果;值越大,褐色程度越高,>=1时元素则完全只剩下褐色(似乎只保留亮度信息)。

    .filter.sepia {
        filter: sepia(1);
    }
    

    image.png

  • drop-shadow(apx, bpx, cpx, color) 投影滤镜,即根据元素形状,设置投影效果。 a, b, c分别表示阴影的水平偏移、垂直偏移、模糊偏移,单位不能为空,必须是具体的尺寸单位,不支持百分比;color表示投影的颜色。

    /* 此处加背景仅仅是让阴影效果更加明显 */
    body {
        background-image: repeating-linear-gradient(-45deg, white 1pxrgba(0,0,0,0.154px, white 1px);
    }
    .drop-shadow {
        filter: drop-shadow(4px 4px 10px #000D);
    }
    

    image.png

    设置方式和CSS box-shadow大致相似。区别在于:

    1. box-shadow仅能够为box设置阴影,而box必然是方形(或border-radius加了圆角的方形),而drop-shadow滤镜在添加阴影时能够考虑对象真实的形状,即文字、SVG、PNG图像Alpha通道等等;

      如图所示,我们分别使用两种方法为test-image.png添加阴影。test-image.png包含四个圆,第一个圆填充为包含透明度渐变的红色,第二个圆填充为不透明蓝色,第三个圆填充为包含从左到右渐变、不透明的黑白两色,第四个圆填充为不透明蓝色,但在中间挖出了一个三角形。

      我们可以着重看看图像被应用阴影滤镜时,第一、第四个圆的投影 —— 因为它们包含透明像素。

    image.png

    得到

    image.png

    1. box-shadow属性值包括6个,按照顺序大致为阴影的水平偏移、垂直偏移、模糊偏移、扩散程度、颜色、以及阴影投影位置(默认为空时在外部投影,设置inset时为在内部投影),但drop-shadow滤镜仅支持水平偏移、垂直偏移、模糊偏移、颜色。
  • hue-rotate(ndeg) 色相旋转滤镜,即对元素的色相进行旋转。(色相的相关内容可参阅github.com/gogoend/gog… ) n为数值,单位常用角度(deg),除此之外还可以用圈数(turn)、弧度(rad),以及刚刚笔者百度到的梯度(grad)。

    .hue-rotate {
        filter: hue-rotate(180deg);
    }
    

    image.png

以上10个属性值是由W3C所规定的。它们之间可以搭配、组合使用(类似transform中的几个属性值),再配合 CSS3 动画/过渡一起享用,可就有很大潜力了哦~

现在来给它们来一张全家福吧:

image.png

当然,filter 属性还支持使用 url 来传入一个自定义滤镜,实现一些更加劲爆的效果,例如置换变形、调色、遮罩等等。

  • url(svg-url) 该属性可用于从外部引入一个SVG滤镜来作用到当前元素上。svg-url表示包含滤镜的SVG文件的路径。滤镜在SVG文件中以id命名,在url中以#id来访问。

    以下是两个示例:

    image.png

    image.png

    如果你有使用过illustrator这款绘制矢量图的软件,可发现其包含了很多预置的使用SVG实现的滤镜。 image 我们可以直接查看其代码,如图所示。 image

笔者实测,发现似乎有个缺憾,自定义滤镜貌似不支持 CSS3 动画/过渡,但可以通过在滤镜内部编写<animate>来实现动画。

SVG滤镜内容很多,对于细节,待我再开一个文章介绍。

2021.7.28 更新:SVG滤镜相关知识点真的好多啊……是的,我暂时还是没写完这篇文章

滤镜的兼容性

还是回到文章开始,参考自:

将页面变灰 - 司徒正美 - 博客园

小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 version="1.1" xmlns="http://www.w3.org/2000/svg">
    <filter id="grayscale">
        <feColorMatrix 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>

结个尾

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

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


总目录:

  1. CSS滤镜篇
  2. 总览篇
  3. 图像引入篇