除了im fine(除了 filter 还有什么置灰网站的方式?)
大家都知道 ,当一些重大事件发生的时候 ,我们的网站 ,可能需要置灰 ,像是这样:
当然 ,通常而言 ,全站置灰是非常简单的事情 ,大部分前端同学都知道 ,仅仅需要使用一行 CSS ,就能实现全站置灰的方式 。
像是这样 ,我们仅仅需要给 HTML 添加一个统一的滤镜即可:
html { filter: grayscale(.95); -webkit-filter: grayscale(.95); }又或者 ,使用 SVG 滤镜 ,也可以快速实现网站的置灰:
<div> // ... </div> <svg xmlns="https://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"/> </filter> </svg> html { filter: url(#grayscale); }大部分时候,这样都可以解决大部分问题 。不过 ,也有一些例外 。譬如 ,如果我们仅仅需要置灰网站的首屏,而当用户开始滚动页面的时候 ,非首屏部分不需要置灰 ,像是如下动图所示 ,该怎么办呢?
看看示意:
这种只置灰首屏的诉求该如何实现呢?
使用 backdrop-filter 实现滤镜遮罩
这里 ,我们可以借助 backdrop-filter 实现一种遮罩滤镜效果 。
filter VS backdrop-filter
在 CSS 中 ,有两个和滤镜相关的属性 -- filter 和 backdrop-filter 。
backdrop-filter 是更为新的规范推出的新属性 ,可以点击查看 Filter Effects Module Level 2 。
filter:该属性将模糊或颜色偏移等图形效果应用于元素 。 backdrop-filter: 该属性可以让你为一个元素后面区域添加图形效果(如模糊或颜色偏移) 。 它适用于元素背后的所有元素 ,为了看到效果 ,必须使元素或其背景至少部分透明 。注意两者之间的差异 ,filter 是作用于元素本身 ,而 backdrop-filter 是作用于元素背后的区域所覆盖的所有元素 。而它们所支持的滤镜种类是一模一样的 。
backdrop-filter 最为常见的使用方式是用其实现毛玻璃效果 。
看这样一段代码:
<div class="bg"> <div>Normal</div> <div class="g-filter">filter</div> <div class="g-backdrop-filter">backdrop-filter</div> </div> .bg { background: url(image.png); & > div { width: 300px; height: 200px; background: rgba(255, 255, 255, .7); } .g-filter { filter: blur(6px); } .g-backdrop-filter { backdrop-filter: blur(6px); } }CodePen Demo -- filter 与 backdrop-filter 对比
filter 和 backdrop-filter 使用上最明显的差异在于:
filter 作用于当前元素 ,并且它的后代元素也会继承这个属性 backdrop-filter 作用于元素背后的所有元素仔细区分理解 ,一个是当前元素和它的后代元素,一个是元素背后的所有元素。
理解了这个 ,就能够明白为什么有了 filter ,还会有 backdrop-filter 。
使用 backdrop-filter 实现首屏置灰遮罩
这样,我们可以快速的借助 backdrop-filter 实现首屏的置灰遮罩效果:
html { position: relative; width: 100%; height: 100%; overflow: scroll; } html::before { content: ""; position: absolute; inset: 0; backdrop-filter: grayscale(95%); z-index: 10; }仅仅只是这样而已 ,我们就在整个页面上方叠加了一层滤镜蒙版 ,实现了只对首屏页面的置灰:
借助 pointer-events: none 保证页面交互
当然 ,这里有个很严重的问题 ,我们的页面是存在大量交互效果的 ,如果叠加了一层遮罩效果在其上 ,那这层遮罩下方的所有交互时间都将失效 ,譬如 hover 、click 等 。
那该如何解决呢?这个也好办 ,我们可以通过给这层遮罩添加上 pointer-events: none ,让这层遮罩不阻挡事件的点击交互。
代码如下:
html::before { content: ""; position: absolute; inset: 0; backdrop-filter: grayscale(95%); z-index: 10; + pointer-events: none; }CodePen Demo -- Gray Website by backdrop-filter
当然 ,有同学又会开始质疑了 ,backdrop-filter 虽好 ,但是你自己瞅瞅它的兼容性,很多旧版 firefox 不支持啊大哥 。我们那么多火狐的用户咋办?
截至至 2022/12/01 ,Firefox 的最新版本为 109 ,但是在 Firefox 103 之前,都是不支持 backdrop-filter 的 。
别急 ,除了 filter 和 backdrop-filter ,我们还有方式能够实现网站的置灰 。
借助混合模式实现网站置灰
除了 filter 和 backdrop-filter 外 ,CSS 中另外一个能对颜色进行一些干预及操作的属性就是 mix-blend-mode 和 background-blend-mode 了 ,翻译过来就是混合模式 。
如果你对混合模式还比较陌生 ,可以看看我的这几篇文章:
不可思议的颜色混合模式 mix-blend-mode 不可思议的混合模式 background-blend-mode CSS 奇技淫巧 | 妙用混合模式实现文字镂空波浪效果 利用混合模式 ,让文字智能适配背景颜色这里 ,backdrop-filter 的替代方案是使用 mix-blend-mode 。
看看代码:
html { position: relative; width: 100%; height: 100%; overflow: scroll; background: #fff; } html::before { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, 1); mix-blend-mode: color; pointer-events: none; z-index: 10; }我们还是叠加了一层额外的元素在整个页面的首屏 ,并且把它的背景色设置成了黑色 background: rgba(0, 0, 0, 1) ,正常而言 ,我们的网站应该是一片黑色的 。
但是 ,神奇的地方在于 ,通过混个模式的叠加,也能够实现网站元素的置灰 。我们来看看效果:
经过实测:
{ mix-blend-mode: hue; // 色相 mix-blend-mode: saturation; // 饱和度 mix-blend-mode: color; // 颜色 }上述 3 个混合模式 ,叠加黑色背景 ,都是可以实现内容的置灰的 。
值得注意的是,上述方法 ,我们需要给 HTML 设置一个白色的背景色 ,同时 ,不要忘记了给遮罩层添加一个 pointer-events: none 。
CodePen Demo -- Gray Website By MixBlendMode
总结一下
这里 ,再简单总结一下 。
如果你需要全站置灰 ,使用 CSS 的 filter: grayscale() 对于一些低版本的浏览器 ,使用 SVG 滤镜通过 filter 引入 对于仅仅需要首屏置灰的 ,可以使用 backdrop-filter: grayscale() 配合 pointer-events: none 对于需要更好兼容性的 ,使用混合模式的 mix-blend-mode: hue 、mix-blend-mode: saturation 、mix-blend-mode: color 也都是非常好的方式有个小技巧 ,在 CSS 的世界中 ,但凡和颜色打交道的事情 ,你都应该想起 filter 、backdrop-filter 和 mix-blend-mode 。
最后
好了 ,本文到此结束,希望本文对你有所帮助 ?
想 Get 到最有意思的 CSS 资讯 ,千万不要错过我的公众号 -- iCSS前端趣闻 ?
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏 。
如果还有什么疑问或者建议 ,可以多多交流 ,原创文章 ,文笔有限 ,才疏学浅 ,文中若有不正之处 ,万望告知。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!