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
相关产品推荐
相关产品推荐

