移动端动画缓动函数怎么自定义才流畅?

UX丽苹 阅读 25

我在用 CSS 做一个下拉菜单的展开动画,用了 transition: height 0.3s ease-out,但感觉不够自然。查资料说可以自定义 cubic-bezier,但我试了几个值效果都不对,要么太生硬要么卡顿。

有没有推荐的缓动函数写法?或者是不是我应该改用 JavaScript 配合 requestAnimationFrame 来控制?比如下面这样写是不是更合适?

.menu {
  transition: height 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
我来解答 赞 2 收藏
二维码
手机扫码查看
2 条解答
设计师景景
直接用 cubic-bezier,试试这个值,感觉还行:
.menu {
transition: height 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}

这个是 ease-in-out 的效果,看起来挺自然的。如果还是不满意,可以试试其他预设的贝塞尔曲线,或者用工具调整直到满意为止。
点赞
2026-03-23 10:09
Des.光远
做移动端动画的时候,确实 cubic-bezier 是个不错的选择,能够让你的动画更加自然。你提到的 cubic-bezier(0.25, 0.46, 0.45, 0.94) 是个比较常用的缓动函数,接近于 ease-in-out 效果,如果觉得不够自然,可以稍微调整一下参数。

CSS 的 cubic-bezier 工具网站比如 cubic-bezier.com 很好用,可以在上面拖动曲线找到适合的效果。一般来说,移动设备上流畅的动画过渡时间在 200ms 到 500ms 之间,你可以试试 transition: height 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); 这种弹跳效果,或者 cubic-bezier(0.77, 0, 0.175, 1) 这种接近于 easeInOutQuad 的效果。

如果觉得 CSS 满足不了需求,可以尝试用 JavaScript 和 requestAnimationFrame,这样可以完全自定义动画过程。不过要注意性能问题,尤其是在低端设备上,频繁操作 DOM 可能会导致卡顿。下面是一个简单的例子:

function animateHeight(element, startHeight, endHeight, duration) {
let startTime = null;
function step(timestamp) {
if (!startTime) startTime = timestamp;
let progress = timestamp - startTime;
let currentHeight = Math.min(startHeight + (endHeight - startHeight) * (progress / duration), endHeight);
element.style.height = currentHeight + 'px';
if (progress < duration) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}

// 使用方法
let menu = document.querySelector('.menu');
animateHeight(menu, 0, 200, 300); // 从 0 到 200px,持续 300ms


这段代码简单实现了从某个高度到另一个高度的动画,你可以根据需要调整起始高度、结束高度和持续时间。记得在实际项目中要做适当的错误处理和边界条件检查。
点赞
2026-03-21 11:03