You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CSS动画缓动函数(ease-in)仅首次生效问题求助(附Demo链接)

搞定滑动缓动失效的问题!

问题拆解

你遇到的情况是:用ease-in做div的上下滑动动画,第一次下滑能看到正常的缓动效果,但从第二次开始,动画就变得生硬,缓动完全没了——这其实是浏览器状态优化导致的小坑。

为啥会这样?

当你点击Slide Up把div高度设为0后,再次点击Slide Down直接把高度改回初始值时,浏览器会觉得“这两个状态变化可以合并”,跳过了过渡动画的触发逻辑。简单说就是,第一次是从“有高度”到“0”再到“有高度”,浏览器能识别到变化;但之后的操作,它默认认为是从0直接跳回目标值,没把这个过程当成需要过渡的动画。

修复方法:强制触发过渡

我们只需要在每次下滑前,给浏览器一个“重新识别状态”的信号,让它知道这是一个新的动画过程。下面是修改后的完整代码:

HTML(不用改)

<button id='slideup'>Slide Up</button>
<button id='slidedown'>Slide Down</button>
<div id="a"></div>

CSS(明确过渡规则)

#a {
  width: 200px;
  height: 200px;
  background: red;
  /* 明确指定过渡的属性和时长、缓动函数 */
  transition: height 0.5s ease-in;
}

JavaScript(核心修复逻辑)

const a = document.querySelector('div#a');
const slideUpBtn = document.getElementById('slideup');
const slideDownBtn = document.getElementById('slidedown');
// 提前保存div的初始高度,避免重复计算
const originalHeight = a.offsetHeight;

slideUpBtn.addEventListener('click', () => {
  a.style.height = '0px';
});

slideDownBtn.addEventListener('click', () => {
  // 第一步:先把高度设为auto,触发浏览器重排
  a.style.height = 'auto';
  // 关键:强制浏览器立即计算元素尺寸,确保状态重置生效
  void a.offsetHeight;
  // 第二步:设置回初始高度,此时浏览器会识别为新的状态变化,触发缓动
  a.style.height = `${originalHeight}px`;
});

关键细节解释

  • void a.offsetHeight:这行代码是关键!它会让浏览器立刻计算元素的高度,相当于给浏览器“刷新”了一下状态,这样后面设置高度的操作就会被当成全新的过渡动画来处理,而不是直接跳过。
  • 保存originalHeight:提前获取初始高度,避免每次点击都重新计算,既提升性能也避免意外问题。

额外小优化

如果想让上滑也有平滑效果,可以把CSS里的缓动函数改成ease-in-out,这样上下滑动都能有自然的动画:

transition: height 0.5s ease-in-out;

内容的提问来源于stack exchange,提问作者user1663023

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:34:58