原文作者:tiutiu
原文链接:https://juejin.im/post/5e86e221e51d4546ce27b99c
为表达全国各族人民对抗击新冠肺炎疫情斗争牺牲烈士和逝世通报的深切哀悼,国务院今天发布公告,决定 2020 年 4 月 4 日(明天)举行全国性哀悼活动。在此期间,全国和驻外使馆下半旗致哀,全国停止公共娱乐活动,4 月 4 日 10 点开始,全国人民默哀 3 分钟,汽车、火车、舰船鸣笛,防空警报鸣响。
想到以往默哀日访问网站时发现整站会变成全灰,即想到如果立即开始开发、设计图修改等工作也会消耗大量的时间与精力,那会不会有 css 可以直接处理所有的元素将他们变灰,随即想到了 css3 的 filter(滤镜),并也证实了这一想法的可行性。
filter: grayscale 使用可以调整元素的灰度值
.gray-filter {
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
- -moz-filter: grayscale(100%);
- -ms-filter: grayscale(100%);
- -o-filter: grayscale(100%);
filter: url("data:image/svg+xml;utf8,<svg 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\'/></filter></svg>#grayscale");
filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
-webkit-filter: grayscale(1);
}
歪马扩展: 歪马删除了原文中的-moz-、-ms-、-o-这些前缀,因为并没这几个前缀,网上的一些教程为了全面都加上了。Caniuse 可以查看,有兴趣的同学可自行在 Caniuse 查询「CSS Filter」。 来源 https://mp.weixin.qq.com/s/6lPfQgjh75067ZQeNk4fKA
以 B 站为例:
在正常的情况下 B 站这个导航栏滑到下面之后是 fixed 在页面的顶部的
但假如你把这段 css 加到了 body 上会发生下面这种情况:
你可以发现它不再固定在页面的顶部了,而是超出去了屏幕外面,屏幕左下角的小电视人也跑到了页面上半部分去,为什么会发生这样的情况呢?
我去 Google 查阅了相关资料,发现:
对于指定了 filter 样式且值不为 none 时,被应用该样式的元素其子元素中如果有 position 为 absolute 或 fixed 的元素,会为这些元素创建一个新的容器,使得这些绝对或固定定位的元素其定位的基准相对于这个新创建的容器。
我们可以联想出 fixed 是相对于 html 根容器来定位的,如果在 body 上设置了 filter 则会创建一个新的定位基准,而页面滚动时将 body 滚动出了屏幕外,则 body 内所有子孙元素的 fixed 将产生不符合预期的效果。
影响全站的方法我们可以将该样式应用到根元素 html 上,即使创建了新的定位基准元素,也不会对子孙元素产生不符合预期的影响。
html {
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
filter: url("data:image/svg+xml;utf8,<svg 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\'/></filter></svg>#grayscale");
filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
-webkit-filter: grayscale(1);
}
效果:
非全站变灰我们可以将需要使用 filter 的元素单独加上
<html>
<body>
<div class="gray-filter"></div>
</body>
</html>
<style>
.fixed {
position: fixed;
top: 100px;
left: 100px;
height: 100px;
width: 100px;
background-color: #f00;
}
.gray-filter {
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
filter: url("data:image/svg+xml;utf8,<svg 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\'/></filter></svg>#grayscale");
filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
-webkit-filter: grayscale(1);
}
</style>
很多小伙伴评论说 IE 低版本不支持该怎么办于是我 Google 搜索了一下是有实现办法的 实现办法是引入 grayscale.js,Demo 下载 grayscale.js Demo[1]
简单查看了该 js 的源码后发现会将 color、background-color、borderColor 等属性提取出来后替换成灰色,background-image 和图片会使用 canvas 绘制处理成灰色再替换成处理后的图片源
demo 内 functions.js 则是对判断浏览器 userAgent 来识别浏览器类型与版本,做出对应的处理
参考资料与 demo 来源[2]
微信小程序我尝试加在 page 上但是 fixed 还是失效了,只能使用第二种方法去加样式,大家如果有解决方案可以评论提出来大家一起讨论一下~
相关文章:
CSS3 filter MDN[3]
兼容 IE 方案的参考资料与 demo 来源[4]
初次发表文章有问题请多多指教,谢谢!
[1]
grayscale.js Demo: http://www.majas-lapu-izstrade.lv/cross-browser-grayscale-ie11/cross-browser-grayscale-ie11.zip
[2]
参考资料与 demo 来源: http://www.majas-lapu-izstrade.lv/cross-browser-grayscale-ie11/
[3]
CSS3 filter MDN: https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter
[4]
兼容 IE 方案的参考资料与 demo 来源: http://www.majas-lapu-izstrade.lv/cross-browser-grayscale-ie11/