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

如何实现CSS元素消失前的滑出动画?汉堡菜单动画故障求助

汉堡菜单滑出动画不生效的解决方法

核心问题

你当前的代码里,当active状态变为false时,<BurgerBar/>组件会直接被从DOM中移除,导致disappear类的滑出动画根本没有执行的机会——组件已经消失了,自然看不到动画效果。而滑入动画能正常工作,是因为组件挂载时会触发slide-in动画。

具体修复步骤

1. 修改Navbar组件:始终保留BurgerBar,用状态控制动画类

不要用条件渲染直接卸载组件,而是通过状态切换类名触发动画,等动画完成后再处理组件卸载(可选)。

export default function Navbar() {
  const [active, setActive] = useState(false);
  const [isClosing, setIsClosing] = useState(false);

  // 监听动画结束事件,完成后重置状态
  const handleAnimationEnd = () => {
    if (isClosing) {
      setIsClosing(false);
    }
  };

  return (
    <>
      <div className={styles.navbar}>
        <Link href='/'>
          <img src="/icons/circle.png" alt="circle" className={styles.circle}/>
        </Link>
        <BurgerButton 
          active={active} 
          setActive={(newState) => {
            if (!newState) {
              // 触发关闭动画
              setIsClosing(true);
              // 等待动画时长(0.3s)后再隐藏组件
              setTimeout(() => setActive(false), 300);
            } else {
              setActive(true);
            }
          }}
        />
      </div>
      {/* 只有激活或正在关闭时渲染组件 */}
      { (active || isClosing) && (
        <BurgerBar 
          isClosing={isClosing} 
          onAnimationEnd={handleAnimationEnd}
        />
      ) }
    </>
  )
}

2. 修改BurgerBar组件:动态切换类名

接收父组件传入的状态,动态添加/移除disappear类:

export default function BurgerBar({ isClosing, onAnimationEnd }) {
  return (
    <div 
      className={`${styles.bar} ${isClosing ? styles.disappear : ''}`}
      onAnimationEnd={onAnimationEnd}
    >
      <ul className={styles.listTitle}>
          <li>
              <Link href='/projet' className={styles.title}>
                  <img src="/icons/laptop.png" alt="laptop" className={styles.iconTitle}/>
                  PROJETS
              </Link>
          </li>
          ...
      </ul>
    </div>
  )
}

3. 优化SCSS代码:调整动画逻辑与初始状态

把动画关键帧移到全局作用域(嵌套在选择器中可能存在兼容性问题),并修正初始位置:

// 全局定义动画关键帧
@keyframes slide-in {
  from {
    right: -100%;
  }
  to {
    right: 0;
  }
}

@keyframes slide-out {
  from {
    right: 0;
  }
  to {
    right: -100%;
  }
}

.bar{
  position: absolute;
  height: 100%;
  width: 30em;
  top: 0;
  right: -100%; // 默认处于屏幕外
  background-color: rgba(0,0,0,0.7);
  padding-left: 7em;

  // 激活时执行滑入动画
  &:not(.disappear) {
    animation: slide-in 0.3s forwards;
  }

  // 关闭时执行滑出动画
  &.disappear{
    animation: slide-out 0.3s forwards;
  }
}

修复要点总结

  • 避免直接卸载组件,通过类名切换触发动画,保证动画完整执行
  • 利用setTimeout和动画结束事件,在动画完成后再更新状态(可选,减少无用DOM节点)
  • 把动画关键帧放在全局作用域,避免嵌套选择器带来的兼容性问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 03:07:45