blur + contrast 滤镜分层组合是唯一稳定跨浏览器的纯css metaball实现方案:小球仅设blur,父容器仅设contrast,需overflow: hidden、will-change: filter及transform缩放。

blur + contrast 滤镜组合是唯一可行的纯CSS方案
真 Metaball(等值面融合)需要实时计算隐式函数与等值线,CSS 无法做到;所有“黏性分离”效果都是视觉错觉。目前唯一稳定、跨浏览器、无需 JS 的路径,就是 filter: blur() 和 filter: contrast() 分层叠加——小球自身只模糊,父容器统一提对比度。其他方案如 clip-path 动画或 mask 渐变,在 Safari 中极易失效或掉帧,且无法模拟拉丝感。
必须严格分层:小球 blur,容器 contrast
常见错误是把两个滤镜写在同一元素上,比如 .ball { filter: blur(5px) contrast(10); },这会让模糊被对比度反向抵消,粘连感完全消失。正确结构是:
- 小球元素(
.dot)只设filter: blur(5px),禁用contrast - 包裹它的父容器(
.gooey-container)只设filter: contrast(10),禁用blur - 容器背景必须是纯色(如
background: #fff),透明或渐变背景会导致对比度失效 - 两个小球需同级、absolute 定位,并用
transform: translateX()移动,避免left/top触发 layout 抖动
参数敏感区:blur(4–6px) + contrast(8–12) 是安全区间
数值偏差一点,效果就断连或崩坏:
-
blur(2px)不够软,交界处仍是硬边;blur(12px)过散,球体轮廓糊成一团,动画中完全看不出分离轨迹 -
contrast(5)粘连感微弱;contrast(20)过曝,小球内部细节断裂、边缘锯齿化 - 实测最稳组合是
blur(5px)+contrast(10),iOS Safari 17.5+ 和 Chrome 128 均表现一致 - 动画时长建议 ≥ 2.5s,用
cubic-bezier(0.7, -0.3, 0.3, 1.4)替代ease-in-out,负 y 值制造初始拉伸,超 1 y 值带来轻微回弹
容易被忽略的渲染前提
即使代码全对,以下三点漏掉任意一个,融合就会“断连”或“闪现”:
- 父容器必须显式声明
overflow: hidden,否则融合过程中球体超出边界的部分会意外溢出 - Safari 需加
will-change: filter到容器上,否则动画掉帧明显(尤其 iOS 17+) - 所有形变(如模拟拉伸的宽高变化)必须走
transform: scale(),不能直接改width/height,否则blur区域不会随缩放重绘
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











