Apple 液态玻璃效果
一、 核心原理
实现这种“液态玻璃”效果的核心在于将 CSS 的磨砂玻璃 (Glassmorphism) 与 SVG 的滤镜扭曲 (Filter Distortion) 相结合。
整个效果可以拆解为三个视觉层级:
- 磨砂层 (Frosted Layer): 使用 CSS
backdrop-filter: blur()对背景进行高斯模糊。 - 液态扭曲层 (Liquid Layer): 使用 SVG
<filter>中的feTurbulence(生成噪点)和feDisplacementMap(置换映射)让光影产生流动和扭曲感。 - 光照与高光层 (Shine Layer): 使用 SVG
feSpecularLighting或 CSSbox-shadow模拟玻璃表面的反光,增加体积感。
二、 最简实现示例 (完整代码)
这是一个提取自 Demo 1 的最小化实现。你可以直接保存为 .html 文件在浏览器打开。这个示例去掉了一切无关的布局代码,只保留核心的液态卡片。
三、 代码深度解析
1. HTML 结构的分离策略
在代码中,我们将 .liquid-layer (负责扭曲) 和 .content-layer (负责文字) 拆分开。
- 原因: SVG 滤镜
feDisplacementMap会极其剧烈地扭曲像素。如果文字和背景在同一个容器内,文字也会变得扭曲无法阅读。 - 解决方案: 使用
absolute定位将液态层铺底,内容层通过z-index浮在上方。
2. SVG 滤镜链详解 (核心魔法)
SVG 滤镜是整个效果的灵魂。以下是 id="liquid-distortion" 内部各标签的详细作用:
<feTurbulence>:- 作用: 生成随机的云雾状/水波状纹理。这是“液体”形态的数据来源。
- 关键属性
baseFrequency="0.01 0.01": 决定波纹的大小。数值越小,波纹越宽大(像平静的水面);数值越大,波纹越细碎(像磨砂)。
<feSpecularLighting>:- 作用: 这是一个 3D 光照效果。它根据
<feTurbulence>生成的纹理的“高度”,计算出光照反射。 - 为什么需要它: 如果只有扭曲,背景只是简单的像素移动。加上光照后,玻璃表面就有了明暗变化,看起来像是有厚度的流体。
- 作用: 这是一个 3D 光照效果。它根据
<feDisplacementMap>:- 作用: 它是“置换滤镜”。它读取
in2(噪声图) 的颜色值,并据此移动in(光照图) 的像素位置。 scale="40": 控制扭曲的剧烈程度。数值越大,液态流动感越强,看起来越“厚”。
- 作用: 它是“置换滤镜”。它读取
3. CSS 的配合
backdrop-filter: blur(6px): 这个属性必须加在滤镜层上。它负责处理背景图片的模糊。SVG 滤镜负责表面的质感,CSS 负责透视的模糊,两者缺一不可。isolation: isolate(可选): 在某些复杂层级中(如 Demo 1 源码所示),添加此属性可以创建一个新的层叠上下文,防止滤镜与其后的背景发生意外的混合计算。
四、 进阶优化与调试
根据 Demo 1 和 Demo 2 的差异,你可以通过调整参数实现不同风格:
| 调整目标 | 修改参数 | 建议值 | 效果参考 |
|---|---|---|---|
| 调整液体稠度 | <feTurbulence> 的 baseFrequency | 0.005 (大波浪) ~ 0.05 (细磨砂) | 越小越像油,越大越像沙 |
| 调整玻璃厚度 | <feDisplacementMap> 的 scale | 20 (薄) ~ 150 (极厚) | 数值大时边缘扭曲极强 |
| 调整光泽度 | <feSpecularLighting> 的 specularConstant | 0.5 (暗淡) ~ 1.5 (高亮) | 决定玻璃的反光强度 |
| 性能优化 | CSS will-change | .liquid-layer { will-change: filter; } | 复杂动画下提示浏览器优化渲染 |
注意: 这种 SVG 滤镜效果在 Safari 和 Chrome 上表现良好,但在性能较差的移动设备上可能会引起掉帧,建议仅对小面积元素(如按钮、Dock 栏、卡片)使用,避免全屏覆盖。
其他实现
1.shader:https://codepen.io/supah/full/dPodbrX 2.WebGPU:https://codepen.io/cjgammon/full/xbGYdbQ
- CSS + SVG Filter:https://codepen.io/lucasromerodb/full/vEOWpYM
https://codepen.io/FlorianWoelki/pen/VYLyOLZ https://codepen.io/Mikhail-Bespalov/pen/MYwrMNy