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

React中用isOpen状态替换group-focus后汉堡菜单X图标不显示

修复React+Tailwind汉堡菜单切换时X图标显示异常的问题

我把Tailwind的group-focus替换为React的isOpen状态实现汉堡菜单切换,参考了第7号图标效果。替换逻辑后,点击按钮时X图标要么完全不出现,要么和汉堡图标同时显示,视觉上没切换成功。

我的代码如下:

import React, { useState } from "react";

export default function HamburgerIcon() {
  const [isOpen, setIsOpen] = useState(false);

  const toggleMenu = () => {
    setIsOpen(!isOpen);
  };

  return (
    <div>
      <button className={`relative group ${isOpen ? "focus:ring-4" : ""}`} onClick={toggleMenu}>
        <div className={`relative
         flex 
         overflow-hidden
         items-center
        justify-center 
        rounded-full 
        w-[50px] 
        h-[50px] 
        transform 
        transition-all
        ring-0 
        ring-secondary 
        hover:ring-8 duration-200 shadow-md ${isOpen ? "ring-4" : ""}`}>
          <div className={`flex flex-col justify-between w-[20px] h-[20px] transform transition-all duration-300 origin-center overflow-hidden`}>
            {/*This is div as Hamburger */}
            <div className={`bg-font-color h-[2px] w-7 transform transition-all duration-300 origin-left ${isOpen ? "rotate-45 translate-y-6 delay-100" : ""}`}></div>
            <div className={`bg-font-color h-[2px] w-7 rounded transform transition-all duration-300 ${isOpen ? "translate-y-6 delay-75" : ""}`}></div>
            <div className={`bg-font-color h-[2px] w-7 transform transition-all duration-300 origin-left ${isOpen ? "translate-y-6" : ""}`}></div>

            {/*This is div with X*/}
            <div className={`absolute items-center justify-between transform transition-all duration-500 top-2.5 ${isOpen ? "-translate-x-10" : "translate-x-0"} flex w-0 ${isOpen ? "w-12" : ""}`}>
              <div className={`absolute bg-font-color h-[2px] w-5 transform transition-all duration-500 ${isOpen ? "rotate-45 delay-300" : ""}`}></div>
              <div className={`absolute bg-font-color h-[2px] w-5 transform transition-all duration-500 ${isOpen ? "-rotate-45 delay-300" : ""}`}></div>
            </div>
          </div>
        </div>
      </button>
    </div>
  );
}

效果截图:
输出效果


问题根源

  1. 汉堡图标未隐藏:isOpen状态下,汉堡的三个bar仅做了位移和旋转,未设置隐藏逻辑,导致和X图标重叠,视觉上X像没显示
  2. X图标过渡逻辑错误:X图标的位移方向搞反,关闭状态下未正确隐藏,且宽度与位移过渡时机不匹配

修复后的代码

import React, { useState } from "react";

export default function HamburgerIcon() {
  const [isOpen, setIsOpen] = useState(false);

  const toggleMenu = () => {
    setIsOpen(!isOpen);
  };

  return (
    <div>
      <button className={`relative group`} onClick={toggleMenu}>
        <div className={`relative
         flex 
         overflow-hidden
         items-center
        justify-center 
        rounded-full 
        w-[50px] 
        h-[50px] 
        transform 
        transition-all
        ring-0 
        ring-secondary 
        hover:ring-8 duration-200 shadow-md ${isOpen ? "ring-4" : ""}`}>
          {/* 汉堡图标容器:打开时隐藏 */}
          <div className={`flex flex-col justify-between w-[20px] h-[20px] transform transition-all duration-300 origin-center overflow-hidden ${isOpen ? "opacity-0 h-0" : ""}`}>
            <div className={`bg-font-color h-[2px] w-7 transform transition-all duration-300 origin-left ${isOpen ? "rotate-45 translate-y-6 delay-100" : ""}`}></div>
            <div className={`bg-font-color h-[2px] w-7 rounded transform transition-all duration-300 ${isOpen ? "translate-y-6 delay-75" : ""}`}></div>
            <div className={`bg-font-color h-[2px] w-7 transform transition-all duration-300 origin-left ${isOpen ? "-rotate-45 translate-y-6 delay-100" : ""}`}></div>
          </div>

          {/* X图标容器:打开时显示,关闭时隐藏 */}
          <div className={`absolute items-center justify-center transform transition-all duration-500 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex w-0 ${isOpen ? "w-10 opacity-100" : "opacity-0"}`}>
            <div className={`bg-font-color h-[2px] w-5 transform transition-all duration-300 delay-200 ${isOpen ? "rotate-45" : ""}`}></div>
            <div className={`bg-font-color h-[2px] w-5 transform transition-all duration-300 delay-200 ${isOpen ? "-rotate-45" : ""}`}></div>
          </div>
        </div>
      </button>
    </div>
  );
}

关键修改点

  1. 汉堡图标添加隐藏逻辑:isOpen状态下给汉堡容器加opacity-0 h-0,让汉堡平滑消失,避免与X重叠
  2. 重构X图标定位:用top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2实现X图标居中,解决原定位偏移问题
  3. 调整X图标过渡逻辑:关闭状态下用opacity-0 w-0隐藏,打开时用opacity-100 w-10显示,配合delay让动画衔接自然
  4. 修正汉堡第三个bar的旋转方向:给第三个bar加上-rotate-45,让汉堡展开动画更合理
  5. 移除冗余focus类:isOpen状态下的focus:ring-4无需保留,按钮的ring状态直接通过isOpen控制即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:34:52