果冻动效本质是利用transform: scale与skewx组合配合弹性缓动函数(如cubic-bezier(0.68,-0.55,0.27,1.55))实现的物理感弹性形变,核心在于仅用transform避免重排、精准控制transform-origin、绑定:active或js交互触发,并满足形变一致、回弹延迟、边缘清晰三要素。

什么是果冻动效(Jelly Effect)的本质
果冻动效不是 CSS 动画库里的标准术语,而是对一类弹性形变动画的俗称:按钮点击时像果冻一样横向拉伸、回弹,常伴随轻微上下浮动。它的核心是 transform: scale() 与 transform: skewX() 的组合 + 弹性缓动函数(cubic-bezier(0.68, -0.55, 0.27, 1.55) 是最常用的一组),不是靠 GIF 或 Canvas 实现。
用纯 CSS 实现可点击的果冻按钮(无 JS)
关键在于把弹性形变绑定到 :active 伪类,并确保按钮有明确的 transform-origin 控制形变中心。常见错误是忽略 user-select: none 导致文字被误选,或未设 touch-action: manipulation 造成移动端延迟。
- 按钮需有固定宽高(百分比或
em均可,但不能依赖内容撑开) - 必须设置
transform-origin: center,否则skewX会绕左上角扭曲 - 动画时间控制在
0.3s以内,过长会显得黏滞;缓动函数必须用自定义cubic-bezier,ease-in-out完全无效 - 为兼容旧版 Safari,需补全
-webkit-transform和-webkit-transition
.jelly-btn {
padding: 12px 24px;
background: #4f46e5;
color: white;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
user-select: none;
touch-action: manipulation;
transform-origin: center;
transition: transform 0.28s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}
.jelly-btn:active {
transform: scale(0.95) skewX(-5deg);
}
用 JavaScript 补充真实交互反馈(避免 :active 失效)
在部分安卓 WebView 或 iOS 滚动中,:active 伪类可能不触发。此时需用 JS 监听 mousedown/touchstart 并添加临时 class。注意:不要用 click,它发生在抬起之后,动效会错位。
- 监听
touchstart和mousedown,同时触发,避免重复绑定 - 动效 class 应在
mouseup和touchend后立即移除,否则残留形变 - 加防抖逻辑:若用户快速连点,避免 class 频繁切换导致渲染卡顿
- 不要在动效中修改
width或height,只用transform——重排(reflow)会严重拖慢动画帧率
const btn = document.querySelector('.jelly-btn');
const handlePress = () => btn.classList.add('is-pressed');
const handleRelease = () => btn.classList.remove('is-pressed');
btn.addEventListener('mousedown', handlePress);
btn.addEventListener('touchstart', handlePress);
btn.addEventListener('mouseup', handleRelease);
btn.addEventListener('touchend', handleRelease);
对应 CSS:.jelly-btn.is-pressed { transform: scale(0.95) skewX(-5deg); }
为什么有些“果冻按钮”看起来假?常见失真原因
真正有物理感的果冻效果,必须满足三个条件:形变方向一致、回弹有延迟感、边缘无像素撕裂。最容易被忽略的是 SVG 或文字在 skewX 下的锯齿问题。
- 使用
will-change: transform可缓解部分浏览器的渲染模糊,但仅在必要时添加(如按钮频繁交互) - 若按钮含图标(SVG),需给 SVG 设置
shape-rendering: crispEdges,否则斜切后边缘发虚 - 字体在
scale(0.95)下可能产生 subpixel 渲染差异,建议搭配text-rendering: optimizeLegibility - 不要对父容器做
overflow: hidden,否则skewX裁剪会导致动画中途突然截断
cubic-bezier(0.68, -0.55, 0.27, 1.55) 这个值不是 magic number,y1/y2 为负/大于 1 才能产生“先压扁再弹出”的过冲感——改一点点,就变成橡皮泥或者弹簧。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











