针对易读性的背景滤镜兼容方案(CSS filter 兼容方案)

原文:Filtered background with fallback for legibility
翻译:涂鸦码龙

你知道现在有多火吗?用这种很大的,高质量的,支持 Retina 屏的模糊的 JPEG 图片作为 header 背景 :

See the Pen Web site header, circa 2016 by Taylor Hunt (@tigt) on CodePen.

潜在的问题是如果浏览器不支持滤镜 filter,文字将不可读 。这违背了可访问性的原则,再完美的视觉也无济于事。

附图1
支持和不支持 filter 的效果对比

因此呢,你需要提前准备好处理模糊的图片,可是设计师偏要你实现动态模糊呢,图片不固定,跟 Apple 的效果一样一样的,咋办?如果是用户上传的图片又咋办?嗯,你需要一台图片处理服务器,听起来成本很高。

我碰巧想到一个妙招,让不支持 filter 的浏览器用颜色图层代替,方案并不完美,但是具有高可读性:

附图2
不支持 filter 的效果

基本实现

我用伪元素作为背景,因为给元素加 filter单纯给背景加 filter 兼容性更好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.backdrop { position: relative }
.backdrop::after {
content: "";
/* 铺满整个父元素 */
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
/* 放到父元素内容的下层 */
z-index: -2;
/* 像父元素一样展示背景 */
background: #222 url("inspirational-landscape-and/or-laughing-with-salad.jpg");
}

加特效

此时,设计师发话了,让背景图模糊一下,再来个轻微变暗效果就更好了。

1
2
/* 不要忘记前缀,Safari >9.1 和所有 Chrome 仍然需要 -webkit- */
filter: blur(4px) brightness(75%);

这么做还远远不够,不支持 filter 的浏览器将严重影响阅读。

上妙招

是否听过 filteropacity() 效果 ?对比广泛支持的 opacity 属性,它显得有点鸡肋,但是它的存在才使得兼容方案得以实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.backdrop::before {
content: "";
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
/* 把它放到其它伪元素的上面,但是仍在父元素内容的下面 */
z-index: -1;
/* 让遮罩层足够的暗,无论什么背景都可以看清楚上面的文字 */
background: rbgba(0,0,0, 0.5);
/* 使用滤镜完全隐藏它?? */
filter: opacity(0%);
}

如果支持 filter 滤镜,带图片的伪元素是模糊的,微微变暗的,这一黑色的遮罩层是完全透明的。如果不支持滤镜呢,显示效果并不完美,但是不会阻碍任何人阅读上面的文字。

CodePen 的例子在此,希望你喜欢:

See the Pen Filtered background with fallback for legibility by Taylor Hunt (@tigt) on CodePen.

其它 filter 滤镜的使用或许也能受此启发,我把它放到了我的锦囊里。

何不用 @supports 代替?

浏览器对 CSS 特性检测(@supports)的支持程度跟 filter 保持一致 ,替换以后代码更加清晰明了:

1
2
3
@supports (filter: blur(4px) brightness(75%)) or (-webkit-filter: blur(4px) brightness(75%)) {
/* 浏览器支持 filter 的话... */
}

你完全可以这么写,全看个人喜好。我查阅了 CanIUse 的使用数据,有一些环境仍不支持 @supports

  • Chrome 18–27
  • Safari 8.x
  • UC Browser 9.9(撰写本文时)

直到2016年5月,以上浏览器的联合使用份额是 ≈ 美国 3.6%、世界范围 10.5%(感谢大洋彼岸 UC 的盛行)。这些数字会随着时间流逝逐渐减少,到那时,如果想写更加清晰的 CSS 就推荐使用 @supports 了。