如何复用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
相关产品推荐
相关产品推荐

