点击收起时没有动画,展开却有。一类原因是收起操作直接把元素隐藏,动画还没播完元素就消失;另一类原因是动画挂在父容器上,而实际位移发生在子列表。

结构
<nav class='mobile-nav'>
<ul class='nav-list'>...</ul>
</nav>
动画应作用在子列表上。挂在导航容器上时,容器高度由内容决定,位移看不出变化。
写法
.nav-list { transform: translateY(-8px); opacity: 0; }
.mobile-nav.is-open .nav-list { animation: slide-in 240ms ease forwards; }
.mobile-nav.is-closing .nav-list { animation: slide-out 200ms ease forwards; }
@keyframes slide-in { to { transform: none; opacity: 1; } }
@keyframes slide-out { to { transform: translateY(-8px); opacity: 0; } }
收起为什么看不到
直接移除展开类会立刻回到初始态,收起动画没有机会播放。做法是增加一个收起状态类,等动画结束事件触发后再移除。
nav.addEventListener('animationend', () => {
if (nav.classList.contains('is-closing')) {
nav.classList.remove('is-closing', 'is-open');
}
});
注意点
- 两个方向的动画分别定义,不要用同一组关键帧反向播放,时长曲线对不上。
- 初始状态写在基础选择器里,避免动画结束后样式跳回。
- 位移用 transform,不对 height 做动画,后者会触发布局计算。
- 尊重系统的减少动效偏好,用媒体查询关闭动画。
