最靠谱纯CSS果冻动画需用transform: scale()配合非均匀缩放、滞后偏移与filter: blur()柔化,辅以will-change: transform和-webkit-transform: translateZ(0)防卡顿闪屏。
transform + filter: blur() 模拟果冻形变最靠谱纯 CSS 实现“果冻”(jelly)动画,核心不是靠 border-radius 变形,而是利用 transform: scale() 配合轻微位移和高斯模糊制造弹性拉扯感。浏览器原生支持好,不依赖 JS,但必须用 will-change: transform 提前声明,否则在 Safari 或低端安卓上容易卡顿或失真。
常见错误是只做上下缩放,结果像气球不是果冻——真正果冻感来自「非均匀缩放 + 滞后偏移」。比如:scale(1.05, 0.95) 同时配 translateY(-2px),再叠加 filter: blur(0.6px) 柔化边缘。
300ms–450ms,太短没弹性,太长像慢动作ease-in-out
width/height 做动画,会触发重排,卡顿明显@keyframes 里要避免用 top/left
top 和 left 触发 layout,果冻动画高频变化下,Chrome DevTools 的 Rendering 面板会立刻标红“Layout Thrashing”。实测同个动画用 transform: translateY() 比用 top 流畅度提升 3 倍以上,尤其在 iOS Safari 上差异更明显。
另一个坑是直接在伪元素(::before)上做果冻变形——如果父容器没设 overflow: hidden,模糊边缘会溢出,视觉上像破洞。建议把果冻效果套在带 border-radius: 50% 的容器内,再用 clip-path: inset(0) 保险兜底。
立即学习“前端免费学习笔记(深入)”;
display: block,inline 元素加 transform 行为不可靠perspective,它会干扰 blur() 的渲染层级vw/vmin 控制基础尺寸,别用 % 配 transform,缩放比例会错乱Safari 对 filter: blur() 的硬件加速支持不稳定,尤其在快速连续触发动画时,会出现一帧白边或位置跳动。根本原因是渲染管线没及时同步 transform 和 filter 的合成层。
最简修复:给果冻元素加 -webkit-transform: translateZ(0) 强制创建独立图层,同时补一句 backface-visibility: hidden。这两句加完,iOS 15+ 基本不闪;iOS 14 仍偶发,就得降级——把 blur(0.6px) 改成 blur(0.3px) 并删掉 filter 动画,只保留 transform。
prefers-reduced-motion 用户的动画:用 @media (prefers-reduced-motion: reduce) 直接切到 scale(1) 静态态animation-play-state: paused 控制启停,Safari 下 resume 容易丢帧,改用 opacity 切换显隐更稳:active 伪类 + transition,比监听 click 再触发动画延迟更低clip-path 做果冻边缘液化比 border-radius 更灵活border-radius 只能做对称圆角,而真实果冻晃动时边缘是不对称“抖动”的。用 clip-path: polygon() 配合 animation 动态改顶点坐标,能做出更自然的液化边缘。例如:clip-path: polygon(50% 0%, 100% 30%, 90% 100%, 10% 100%, 0% 30%),再逐帧微调几个百分比值。
注意:Firefox 对 clip-path 动画支持差,polygon() 帧间插值不平滑。稳妥做法是只在 Chrome/Edge/Safari 用 clip-path,其他浏览器 fallback 到 border-radius + transform 组合。
clip-path 坐标必须用百分比,像素值在缩放时会错位clip-path 动画里混用 inset() 和 polygon(),浏览器解析行为不一致pointer-events: none 到 clip-path 层,否则点击区域会偏移blur() 像素值没随设备像素比缩放,或者 transform 的位移量没按 devicePixelRatio 微调。这些细节不报错,但用户一眼就觉出“假”。