虽然对比度、饱和度和模糊等滤镜在图像编辑器中已经存在了一段时间,但在网络上实现它们历来需要提供已经应用了这些滤镜的图像。 随着浏览器开始将滤镜作为 Web 平台的一部分来整合,我们可以开始将复杂的视觉效果分解为它们的组成部分,并在网络上实现它们。 本文将研究一种这样的效果,磨砂玻璃,以及 CSS 滤镜如何提供比静态图像更清洁、更灵活的解决方案。
老派:使用图像制作磨砂玻璃效果
磨砂玻璃效果在互联网上已经存在了一段时间;我们甚至在 2008 年的 CSS-Tricks 上看到了它 back in 2008。 该效果背后的理念很简单:只需模糊并淡化覆盖内容后面的区域。 内容与其背景获得更高的对比度,但您仍然可以大致了解背景上的内容。 CSS-Tricks 文章使用了两张图片:标准版本和磨砂版本(模糊并带白色色调)。 在我们的示例中,卡片向上滑动以显示内容,同时对背景进行磨砂处理。
演示
查看 CodePen 上 betravis (@betravis) 制作的笔 使用多张图片制作的磨砂玻璃效果。
HTML
标记非常简单。 我们只有一个包含内容的文章。
<article class="glass down">
<h1>Pelican</h1>
<p>additional content...</p>
</article>
CSS
我们首先将所有内容的大小调整为视窗。 然后,我们在原始背景之上叠加模糊的背景版本。 最后,我们添加白色色调。 溢出隐藏,以防止滚动并将效果裁剪到 .glass
元素。
html, body, .glass {
width: 100%;
height: 100%;
overflow: hidden;
}
body {
background-image: url('pelican.jpg');
background-size: cover;
}
.glass::before {
display: block;
width: 100%;
height: 100%;
background-image: url('pelican-blurry.jpg');
background-size: cover;
content: ' ';
opacity: 0.4;
}
.glass {
background-color: white;
}
上面的 CSS 将创建我们的模糊和淡化叠加层。 我们还需要将叠加层向下移到页面底部,只留出足够的空间来查看标题文本。 由于模糊图像是在叠加层的子元素中,我们还需要将其向上移动相反的距离,以便将其与主体背景保持一致。 由于演示使用的是过渡,我选择使用 CSS 转换而不是 background-attachment
属性,因为 CSS 转换可以进行硬件加速。
.glass.down {
transform: translateY(100%) translateY(-7rem);
}
.glass.down::before {
transform: translateY(-100%) translateY(7rem);
}
.glass.up, .glass.up::before {
transform: translateY(0);
}
笔记
以上技术很简单,并且具有良好的浏览器支持。 尽管我使用 过渡 对演示进行了稍微修饰,但其他所需功能(生成内容、不透明度、转换 和 背景大小)都具有良好的浏览器支持,可以追溯到 IE 9(除了 Opera Mini)。
新派:使用滤镜制作磨砂玻璃效果
重复图像技术要求维护模糊图像和原始图像,如果您需要为多个图像重复使用该效果,这会很麻烦。 例如,响应式设计可能需要在不同的屏幕尺寸下交换不同的图像。 或者,模板布局可能会动态地插入图像(例如,每个博客文章使用不同的标题图像)。 对于这些情况,如果只使用源图像就能生成效果会很棒。 毕竟,我们只是模糊了它。
这就是 CSS 滤镜大显身手的地方。 它们允许我们在浏览器中使用 CSS filter
属性 应用模糊效果。
CSS
我们可以调整磨砂玻璃叠加层的 CSS,使其成为应用了 blur
滤镜的原始图像。
.glass::before {
background-image: url('pelican-blurry.jpg');
}
.glass::before {
background-image: url('pelican.jpg');
filter: blur(5px);
}
演示
查看 CodePen 上 betravis (@betravis) 制作的笔 使用滤镜效果制作的磨砂玻璃效果。
注意事项
很简单,对吧? 不幸的是,CSS 滤镜相对较新。 这意味着它们可能带有供应商前缀,并且它们的 浏览器支持 还没有普及。 但是,滤镜在 SVG 中有更长的历史,并且通过 CSS 将 SVG 滤镜应用于 HTML 内容 具有更广泛的浏览器支持。 您只需将它们添加为 CSS 滤镜不支持时的后备选项即可。 上面的演示实际上就是这么做的。
要添加 SVG 滤镜,我们在 HTML 标记中包含一些内联 SVG,并使用 url()
引用滤镜。 专业提示:另一种选择是编码 SVG 滤镜并将其引用为数据 URL,但这种格式在文章中有点难以阅读。
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5" />
</filter>
</defs>
</svg>
.glass::before {
background-image: url('pelican.jpg');
/* Fallback to SVG filters */
filter: url('#blur');
filter: blur(5px);
}
仍然会有一些情况,浏览器不支持 CSS 或 SVG 滤镜。 在这种情况下,用户将在淡化(带色调但未模糊)的背景上看到文本,这还不错。
结论
滤镜允许我们在浏览器中使用以前仅在图像编辑器中可用的效果。 作为元素的样式,而不是渲染的图像,它们更容易修改和重复使用。 您可以在当前版本的 Chrome、Safari 和 Opera 中使用 CSS 滤镜,并且它们正在 Firefox 中积极开发(目前还没有关于 Internet Explorer 的消息)。 只要对后备行为稍加注意,您就可以从今天开始使用它们。
在新学校 CSS 之前的示例中。 你是想用 pelican.jpg 而不是 pelican-blurry.jpg 吗? 如果我错了,请随意删除我的评论。
@Jared:在“新学校”示例中,他使用的是“filter: blur(5px);”,所以不需要 pelican-blurry.jpg。 这就是它被称为新学校的原因。
是的,我同意这是一个错别字
@Jared、@Strve:你们指的是“新学校”部分开头的“CSS 之前”和“CSS 之后”部分吗? 我应该更清楚地划分它们,但“CSS 之前”应该是代表老派(pelican-blurry.jpg)语法,而“CSS 之后”则展示了调整后的新派(pelican.jpg + 模糊滤镜)语法。 我想,我还在 CSS 中使用“::before”伪元素,这也帮不了什么。
不错 :)
当拟物化设计风靡一时的时候,它会很酷,但现在有点过时了。 不过仍然令人印象深刻。
在复制文本和背景图像之间增加对比度永远不会过时。这只是其中的一种方法。
你是说苹果在最新的 iOS 中 加入了 这种效果吗?
我认为 CSS 过滤器最大的问题仍然是性能。我记得最近我试图在一个全尺寸的视网膜图像上实现类似的磨砂效果,即使在我的 12 核 Mac Pro 上,Chrome 突然也难以滚动页面,任何 CSS 过渡都变得不可能。
大约一周前,我也遇到了同样的问题。我从我正在创建的应用程序中删除了这种效果。它在少量使用时效果很好,但在没有妥善处理时会严重消耗 CPU。
@ryab, @mike: 这种效果可能很昂贵,尤其是在处理大型图像时。如果你们两位能分享一些性能开始出现问题的例子,我会非常乐意看看。我能给出的唯一建议是,对于动画和过渡,让效果更 适合 GPU 有时会有所帮助。
@Bear 如果网络上有一个一次编写、随处运行的解决方案,并且已经支持了所有这些效果,那该多好啊 ;P
我使用过滤器表达式做了类似的事情 (http://codepen.io/jamespr/pen/aipgo)。很高兴看到这种效果。
我不应该为浏览器使用前缀吗?
我的 Pen http://codepen.io/Shaz3e/pen/qJwnx/
@Shaz3e,
只需要 -webkit,它在演示中使用。
https://caniuse.cn/css-filters
@Shaz3e: 是的,您可能需要使用供应商前缀,尽管正如 Dan 提到的,目前只支持 -webkit。演示使用 Prefix Free,但我必须显式添加 -webkit 过滤器变体。我还选择将浏览器支持简化为 IE 9 及更高版本,因此放弃了 旧的 IE 过滤器语法(IE 9 已弃用,IE 10 及更高版本不支持)。
感谢 @Dan Mathisen 和 @Bear Travis 的评论,我认为我应该开始在下一个项目中使用 Prefix Free。
太棒了!我一直都在寻找更简单的方法来集成 iPhone 模糊背景和滚动效果。我迫不及待地想要它被更广泛地接受!
我认为我发现了一个缺陷……使用新的 Google Chrome,我在我的 Android 4.4 KitKat 版本上看不到模糊效果?还有其他人遇到这个问题吗?
是的,我也遇到了。
关键(不需要的)区别:羽化边缘。CSS 过滤的图像会产生柔软的羽化边缘,据我所知,没有办法剪切它们。即使在较小的元素内裁剪并使用 overflow:hidden 时,浏览器也会对图像的可见部分应用模糊效果。我发现的唯一可以实现清晰模糊效果的解决方案是使用 canvas 导入图像数据,对数据运行模糊过滤器,并使用 toDataURL 导出模糊图像,或者使用 canvas 本身。
在此查看一些不错的模糊效果:https://github.com/Quasimondo/QuasimondoJS/tree/master/blur
#protip – 将图像导入到较小的 canvas 中(无论如何这是一个有损过程),但它可以克服 Safari 中的一个狭窄瓶颈。
我使用这种技巧对视频进行了很好的效果,实现了全面的 60fps。在 Twitter 上联系我(@furf),我会发布代码示例。
示例 canvas 模糊实现覆盖在视频上(如上所述)。
http://www.furf.com/exp/video-blur/
我同意羽化边缘可能有点令人沮丧。在某些情况下,您可以剪切一个略微更大的模糊图像元素到其父元素以获得清晰的边缘。我快速 模拟 了这篇文章中的演示示例的样子。
很好。由于某种原因,我之前一直无法让裁剪工作。我需要重新审视我的演示 :) 谢谢!
CSS 模糊过滤器在框架处产生难看的渐变。
非常酷的东西。有趣的是,旧版在我 Safari 6.1 上不起作用。
如果使用
filter:blur()
,您是否可以使用inherit
来获取 background-image 值,从而避免重复 URL?不幸的是,在本例中不行,因为 .glass::before 的父元素是 .glass,并且背景图像是在 body 上设置的。
FWIW,这在 IE12 中 “正在考虑”。
前段时间我一直在玩 CSS 过滤器和滚动。
两个笔供您享受 css
动态内部模糊
动态外部模糊
@Kseso 感谢您的想法。
我一点也不喜欢新版。模糊属性破坏了清晰的边缘,并在图像周围添加了一个光晕。
我真的很讨厌模糊属性
“并在图像周围添加了一个光晕”
我没有看到。什么浏览器?我在 Chrome 33 上。
光晕非常小,但在上面的演示中仍然存在。
提高模糊度和不透明度,您就会看到它。
Chrome – 版本 33.0.1750.152
我将鹈鹕图像放大到 400%,但没有看到任何光晕。那可能是个人感知的视觉扭曲。
如果我们能够在没有第二个图像实例的情况下实现这一点,那就更好了。我知道很多人(包括我自己),都在寻找在下面的非图像 html 元素上叠加磨砂效果的方法。如果叠加层是全屏的,则有解决方法,但如果磨砂效果需要在屏幕中间被截断,则没有。
太棒了,这正是我想要的。非常感谢。
你好
我有点困惑,我重新创建了 CodePen,但它看起来并不一样,好像没有获得正确的字体(Source Sans Pro)?您知道为什么会这样吗?
最后,我只是将您的 HTML、CSS 和 JS 从您的复制到我的,但仍然一样
我的 Pen 我的 Pen 和您的 您的 Pen
找到了,需要更改 CSS 的设置并加载字体!!只是现在才注意到 CodePen 上的设置齿轮
由于某种原因,当我将这种理论应用于 flexbox 项的绝对定位伪元素内的背景图像,并进行旋转时,它会在 Firefox 中禁用背景图像本身。很奇怪,即使我在禁用所有样式后,除了过滤器和背景图像(甚至是 content: ”;),它仍然无法工作。
我想知道是否真的有一个具体的解决方案。我在 StackOverflow 上找到了参考资料,但这些解决方案似乎都不起作用。
可以使用视频背景吗?
http://furf.com/exp/video-blur
使用 canvas 实现。