质感 · 材质

毛玻璃

毛玻璃后面滚过什么内容,你控制不了。字的对比度只能按最坏情况算。 好在最坏情况是能算出来的,不用猜。

模糊只是平均

backdrop-filter: blur() 做的事是把后面的像素做加权平均。 平均值有个性质:一定落在参与平均的那些值的最小和最大之间, 不会造出比最亮的还亮、比最暗的还暗的颜色来。

所以不管后面滚过什么,玻璃的成色都夹在两个极值之间: 蒙层压纯黑,和蒙层压纯白。字对这两块的对比度里差的那个,就是最坏情况。 要是字的亮度正好落在这两块之间,那就存在某种内容让字和玻璃一样亮,字直接消失。

举个常见的:白蒙层 30%,配 #333333 的深灰字。后面是浅色页面时很好看, 后面滚过一张深色图片时玻璃只剩 , 字对它 。要让这个字色在任何内容上都过正文线, 白蒙层至少 。

动手

演示底下那排刺眼的色块,就是「后面滚过的内容」。玻璃板下面两块是两个极值的实际成色, 字直接压在上面,能不能读一眼就看得出来。

蒙层要多不透明,字才在任何内容上都读得出来

深色下

深色主题的玻璃是深蒙层配浅字,最坏情况变成后面滚过一片白: 深色蒙层 #101116 配白字,要在任何内容上过 4.5:1, α 至少 。 把上面的蒙层色和字色换过来,两套主题各算一遍,别把浅色那个 α 抄到深色里。

两条写法上的事

  • -webkit-backdrop-filter 还得带着,Safari 到现在都要前缀。
  • 不支持的浏览器不会模糊,半透明蒙层后面的内容原样透出来,字压在内容上。 导出的那段里有一条 @supports not,退成不透明蒙层, 这时字的对比度就是字对蒙层本身,导出的注释里写着那个数。

这是上界,不是精确值。极值是按「后面可能出现纯黑和纯白」算的, 你要是能保证后面只有自己的页面底(比如一个固定色的侧栏上的浮层), 直接去透明度那页按实底算就行,能省不少 α。

saturate()、brightness() 这类叠在 blur 上的滤镜没算进来, 它们会把区间挪一挪,但不改变「夹在两个极值之间」这件事。