您可以使用 filter
属性 非常轻松地将滤镜应用于整个元素。但是,如果您只想将滤镜应用于元素的背景怎么办?这有点棘手。
有一些 CSS 属性专门用于背景,例如 background-blend-mode
——但混合和滤镜不是一回事。这似乎是我们拥有 backdrop-filter
的原因,但并不完全如此。它会根据背景与元素后面的内容交互方式进行滤镜处理。
不幸的是,没有 background-filter
属性。我们该怎么办呢?
使用伪元素代替背景
如果将元素的内容放在内部包装器中,则可以在一个伪元素之上设置它,该伪元素只是假装是背景。
.module {
position: relative;
}
.module::before {
content: "";
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background-image: url(graphic-to-be-filtered.jpg);
filter: grayscale(100%);
}
.module-inside {
/* This will make it stack on top of the ::before */
position: relative;
}
查看 Chris Coyier 的 CodePen 将滤镜应用于伪元素 (@chriscoyier) 在 CodePen 上。
看到“背景”如何使用 grayscale
进行滤镜处理了吗?我们在那里调用了灰度滤镜,并将其仅应用于伪元素,而内部的其他内容则保持未过滤状态。
这取决于您想要哪种滤镜……您也许可以使用混合模式来伪造它
我遇到这个问题是因为我特别想将元素的背景图像转换为灰度。正如我们所讨论的,由于没有专门针对此目的的属性,因此我考虑了 background-blend-mode
,特别是它如何为诸如饱和度和颜色之类的属性提供混合选项。如果我可以在图形顶部设置纯黑色,那么我就可以将它们混合——就像我使用 多个背景 一样——并且基本上可以伪造灰度效果。
请注意,在使用多个背景时,您不能单独使用纯色(那将是 background-color
而不是 background-image
),因此我们也必须使用无过渡的 linear-gradient
来伪造它。
.module {
background-image:
linear-gradient(black, black),
url(image-to-be-fake-filters.jpg);
background-size: cover;
background-blend-mode: saturation;
}
查看 Chris Coyier 的 CodePen 使用混合模式应用伪造的滤镜 (@chriscoyier) 在 CodePen 上。
Dan Wilson 的探索
Dan 深入研究了这个问题,并制作了一个探索性的 CodePen,其中包含三个图层
- 顶层:来自
radial-gradient
的晕影 - 中间层:纯色
- 底层:图像图形
您可以调整前两层中使用的颜色,并对每一层应用不同的混合模式。这是我学到的另一件事!就像您可以使用逗号分隔符创建多个背景(以及类似地使用 background-size
、background-position
等将这些值应用于特定背景)一样,您还可以使用逗号分隔符将 background-blend-mode
应用于每一层,从而对每一层应用不同的混合效果。
查看 Dan Wilson 的 CodePen 多个背景,多个混合模式 (@danwilson) 在 CodePen 上。
感谢您提供精彩且内容丰富的文章,我不知道没有您我会怎么办!Material Design 的“蒙版”滤镜也很不错,请查看:https://mdbootstrap.com/css/masks/
规范中确实存在一个
filter(<image>, <filter-function-list>)
函数,它应该处理此用例和其他用例,允许您直接将滤镜应用于 CSS 中的任何图像。但是……还没有浏览器率先实现它。
我来这里就是想说这个,但当然 Amelia 会抢在我前面。 :)
但是!Safari 从 Safari 9 开始支持(非常 buggy),然后从 iOS 9.1/10 开始取消前缀,bug 少一些,如果我没记错的话。
另一个不涉及伪元素的技巧是使用带有 feColorMatrix 的 base64 编码的 svg。
这对我的 css 有效