🐏 Web 实现 Fluent UI 的 Acrylic 亚克力效果和组件库的能力
IOS 上的背景模糊效果真的非常的惊艳,从 CSS backdrop-filter 这个属性可用以来就实验性的玩过,除了兼容性问题上硬伤(目前 86% 左右,尤其是国内 X5 内核等魔改内核(微信和很多 APP 内置的浏览器)),效果还是很不错的。
前两天又看到了微软的 Fluent Design,Fluent Design System 可帮助你创建包含光线、深度、动画、材料和比例的现代粗体 UI。
其中看到了 UWP 设计和 UI 中介绍的一个效果:亚克力材料。Acrylic 是一种 Fluent Design 系统组件,用于在你的应用中添加物理纹理(材料)和深度。
详细可以查看具体的文章: 亚克力材料
最后整个效果的实现,有讲需要几个效果叠加:
按照说法:
我们微调 Acrylic 的关键组件以凸显其独特外观和属性。 我们从半透明度、模糊和噪点设置开始,为平滑图面增添视觉深度和维度。 我们添加了排除混合模式层,以确保放置在 Acrylic 背景上的 UI 的对比度和可读性。 最后,我们添加了各种颜色色调,以供用户进行个性化设置。 这些图层协同作用,形成了全新的实用材料。
所以亚克力效果不仅仅是背景模糊,还需要考虑:
- 背景
- 模糊
- 排除混合
- 颜色/色调覆盖
- 噪点
CSS 来试试实现这个效果(请使用 Chrome V76+;从左到右为各个效果叠加的过程;源码在最下面):
Hello World
blur: 30px;
brightness: 120%
color: hsl(50, 50%, 50%)
color-saturate: 80%
color-opacity: 0.2%
noise-opacity: 0.8%
noise-scale: 30%
brightness: 120%
color: hsl(50, 50%, 50%)
color-saturate: 80%
color-opacity: 0.2%
noise-opacity: 0.8%
noise-scale: 30%
左边的悬浮菜单是 CSS 实现的,看起来还是很精致的:
CSS Effect
Archive
Delete
Move
Set Flag
Mark as Read
Move to Junk
Move to Other
Always move to Other
大部分宣称玻璃效果的 CSS 实现,基本上就是只应用到了
backdrop-filter: blur(30px);
一个属性,很多时候背景如果颜色不太搭配,会出现普适的文字对比度、颜色效果等不协调,所以业务中用到很少。apple 官网的效果用到了
backdrop-filter: saturate(200%) blur(20px);
加上一个 background-color
可以实现整体色调和饱和度调整,效果好很多。我这里实现的整个效果并没有按照亚克力官方的各个层级来实现,主要是 CSS 的混合模式 mix-blend-mode 和想要的效果并不一致,没办法叠加上去,所以基本上用的还是 backdrop-filter 属性。
用到的属性有:
backdrop-filter: blur(30px);
负责背景模糊,这个是最基础的效果,如果仅使用这个效果也可以,但是可能没办法个性化效果。backdrop-filter: brightness(120%);
负责亮度,将整个效果变亮还是减暗,主要可以用在暗黑还是亮色主题。background-color
负责添加颜色色调,主要的个性化属性,需要配合 opacity 避免影响后面的透明度。backdrop-filter: saturate(80%);
负责饱和度,太鲜艳的背景色会干扰前景信息,这个可以稍微压一下饱和度。background-image
负责添加一个噪点层,主要是提供亚克力磨砂哑光的效果。
相比 apple 的效果添加了一个 brightness 来调整背景亮度,不需要颜色层的深浅来承担这个效果。然后颜色层更多的是进行个性化的颜色调整。最后是添加噪点层,增加磨砂效果,这个效果可能没那么明显,不过仔细看可能观感舒服一点点。
backdrop 可以同时添加多个滤镜,所以:
.acrylic {backdrop-filter: blur(30px) brightness(80%) saturate(160%);background-color: rgba(x, x, x, .5); /* 这里如果添加颜色个性设置,需要有透明度,不然看不到后面 */background-image: url(...); /* 噪点的图片 */}
这样就实现了很简单的一个亚克力效果,同时亮度和饱和度的调整能够满足大部分的前景对比度。
亚克力的效果需要背景、亮度、饱和度等属性配合,一旦这几个属性没搭配好,跟前景的内容对比度不高,就会导致可读性问题。所以调整效果的时候一定要精心调整,避免不透明度、颜色、亮度等混在到前景内容中,造成识别困难,效果自然没办法保证。
比如上面的 brightness 如果调整很高,加上前景文字如果是白色,那么文字基本上就是没办法阅读了。
官网也重点强调:
请务必确保应用上显示的任何文本满足对比率要求。 我们已优化 Acrylic 设置,因此,增强色的黑色、白色甚至中间色的灰色文本在 Acrylic 上显示时都能满足对比率要求。 平台提供的主题资源的默认对比色调为 80% 不透明度。 在 Acrylic 上放置增强色正文文本时,你可以在降低色调不透明度的同时保持可读性。 在深色模式下,色调不透明度可设为 70%,而在浅色模式下,Acrylic 可满足 50% 不透明度条件下的对比率要求。 不建议在 Acrylic 图面上放置颜色鲜亮的文本,因为这种组合可能无法满足 15 像素字体大小时的最低对比率要求。 请尽量避免在 Acrylic 元素上放置超链接。 此外,如果选择自定义设置 Acrylic 色调颜色或不透明度,而不采用主题资源提供的平台默认设置,请时刻注意可读性。
- 父组件如果使用 will-change: transform 属性,back-drop: blur 可能不会生效。
- position: absolute; 的上层 mix-blend-mode 可能会把下层的 back-drop: blur 属性失效。
CSS Effect
Archive
Delete
Move
Set Flag
Mark as Read
Move to Junk
Move to Other
Always move to Other
再多一点,每篇文章不仅仅写一个东西,最后如果多花一些时间提炼出点什么、产出什么,那么文章不仅仅是总结,更是能产生持续的价值。这里将这个亚克力效果为主题实现一个组件库。
组件库的实现是很复杂的,一般是团队沉淀,维护更是耗时耗力,改进和添加组件更是海量工作,但是还有一个比较轻量省事的途径:做主题。
比如比较知名的 @material-ui 就包含了很多非常高质量的组件,非常友好、Tree-Shaking、图标、交互体验、完整的设计规范、完善的 TypeScript 的支持、甚至包含无障碍的支持,更重要的是支持主题。这里我们在这个组件基础上做一个主题效果。
点进去查看:亚克力效果的组件库,包含按钮、弹窗、菜单、警示条、对话框等亚克力效果组件。
Menu 的例子:
感谢您的阅读,本文由 Ubug 版权所有。如若转载,请注明出处:Ubug(https://ubug.io/blog/fluent-acrylic)