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

如何复用CSS关键帧实现动画反向播放?

复用单个CSS关键帧实现展开/收起反向动画问题

我目前用两个关键帧expandTop和collapseTop分别实现元素的展开与收起动画,通过切换CSS类触发。现在想复用同一个@keyframes实现反向播放,但尝试reverse、backwards等属性组合后无效,该如何解决?

现有代码

@keyframes expandTop {
  from {
    height: 0;
  }
  to {
    height: 100px;
  }
}
&.expand {
  animation: expandTop 0.5s ease-out forwards;
}
@keyframes collapseTop {
  from {
    height: 100px;
  }
  to {
    height: 0;
  }
}
&.collapse {
  animation: collapseTop 0.5s ease-out forwards;
}
&.still {
  animation: none;
}

期望实现的代码形式

@keyframes top {
  from {
    height: 0;
  }
  to {
    height: 100px;
  }
}
&.expand {
  animation: top 0.5s ease-out forwards;
}
&.collapse {
  animation: top 0.5s ease-out reverse backwards;
}
&.still {
  animation: none;
}

解决方案

问题出在你添加的backwards属性上:backwards会在动画开始前应用关键帧的from状态(也就是height: 0),导致切换到.collapse类时元素先跳变到0,再反向播放,完全不符合预期。

修正后的代码只需去掉backwards,保留reverse和forwards即可:

@keyframes top {
  from {
    height: 0;
  }
  to {
    height: 100px;
  }
}
&.expand {
  animation: top 0.5s ease-out forwards;
}
&.collapse {
  animation: top 0.5s ease-out reverse forwards;
}
&.still {
  animation: none;
}

原理说明

  • 当元素处于.expand状态时,animation-fill-mode: forwards会让动画结束后保持height: 100px的状态。
  • 切换到.collapse类时,animation-direction: reverse会让动画从关键帧的to状态(100px)反向播放到from状态(0)。
  • forwards属性会在动画结束后保持最终帧(也就是0)的状态,实现收起效果。

额外注意事项

如果直接从.expand切换到.collapse时动画未触发,可以通过JavaScript强制触发动画重新执行:

// 假设element是目标元素
element.classList.remove('expand', 'collapse');
requestAnimationFrame(() => {
  element.classList.add('collapse');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:01:07