液态玻璃是怎么在浏览器里折射的
约 8 分钟
Apple 在 WWDC 2025 带来的 Liquid Glass 让整个界面像浸在玻璃里。它的核心不是模糊,而是折射——边缘把背景弯出一个透镜。在浏览器里复刻它,靠的是一组低调但强大的 SVG 滤镜原语。
位移贴图:一张图决定光怎么弯
feDisplacementMap 的工作方式很朴素:它读一张图,用像素的 R 通道决定横向位移、G 通道决定纵向位移。灰色(128,128)就是「不动」。所以问题变成:如何画一张「透镜」形状的位移图。
// 圆角矩形内缩一层,边缘模糊——形成一圈透镜带
rect(x + depth, y + depth,
width - depth * 2, height - depth * 2,
fill: "#808080", // 中性:中心不弯
filter: blur(depth))
一个内缩并模糊的圆角矩形叠加在灰色底上,边缘就得到了一圈从「弯」到「不弯」的渐变。玻璃的厚度感,来自这个渐变带的宽度。
色差:让白光散开
真实玻璃有色散——不同波长的光折射角度不同。做法是把同一位移跑三遍,三次的位移强度递减,各自只保留一个颜色通道,再用 screen 混合叠回来:
R ← 位移 (strength + 2ca)
G ← 位移 (strength + ca)
B ← 位移 (strength)
于是边缘出现细密的彩色镶边,人眼立刻读懂「这是一片有厚度的玻璃」。
只折背景,不折内容
backdrop-filter 是整个方案的关键:它把滤镜应用在元素背后的内容上,元素自身的内容层级完全不受影响。玻璃归玻璃,文字归文字——这也是 Apple 反复强调的纪律:玻璃属于控件层,永远不要糊在正文上。
浏览器的现实
backdrop-filter: url(#filter) 目前只有 Chromium 支持。Safari 和 Firefox 需要降级为 blur + saturate 的毛玻璃——检测时注意 Firefox 会把 url() 解析为合法值却什么也不渲染,任何基于样式解析的检测都会被它骗过,老老实实用 UA 判断吧。
把这些拼起来,再加上随指针移动的镜面高光,就是你现在在这个页面上看到的玻璃。