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

如何在React JSX中实现汉堡菜单铺满整页效果

实现全屏白色背景的汉堡菜单(React + Tailwind CSS)

我是React JSX新手,正在学习使用Tailwind CSS。目前已实现导航栏的汉堡菜单,但样式不够整洁,希望实现白色背景铺满整页的汉堡菜单效果。以下是我的Navigation组件代码,求修改帮助:

import logo from "./favicon.png";
import { motion } from "framer-motion";
import { useInView } from "react-intersection-observer";
import MenuDropdown from "./MenuDropdown";
import { Link } from "react-router-dom";
import { useState } from "react";

export default function Navigation() {
  const [ref, inView] = useInView({ triggerOnce: false });
  const [isOpen, setIsOpen] = useState(false);

  const [navVisible, setNaVisible] = useState(false);

  const megaMenu = document.getElementById("mega-menu");

  return (
    <motion.nav
      className="flex items-center justify-between flex-wrap px-6 lg:px-12 py-8 max-w-full mx-auto"
      ref={ref}
      initial={{ y: -10, opacity: 0 }}
      animate={inView ? { y: 0, opacity: 1 } : {}}
      exit={{ y: -10, opacity: 0 }}
      transition={{ duration: 0.5 }}
    >
      <a
        href="/"
        className="flex flex-row items-center flex-shrink-0 text-white mr-6 lg:pr-16 space-x-2"
      >
        <img src={logo} className="w-8 h-8" alt="Logo"></img>
        <h2 className="font-bold text-2xl tracking-tight">Jibu Labs</h2>
      </a>

      <div id="menu" className="block lg:hidden">
        <button
          className="flex items-center px-3 py-2 border rounded text-slate-200 border-slate-400 duration-100 hover:text-white hover:border-white"
          onClick={() => setNaVisible(!navVisible)}
        >
          <svg
            className="fill-current h-3 w-3"
            viewBox="0 0 20 20"
            xmlns="http://www.w3.org/2000/svg"
          >
            <title>Menu</title>
            <path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" />
          </svg>
        </button>
      </div>
      <div
        className={`
        ${navVisible ? "w-full block flex-grow g:flex lg:items-center lg:w-auto" : "lg:flex flex-none w-6/12 hidden lg:content-right"}`}
      >
        <div
          className={`
        ${navVisible ? "lg:flex-grow flex flex-col  text-sm" : "lg:flex-grow flex flex-rows space-x-12 text-sm "}`}
        >
          <div
            className={`${!navVisible ? "flex flex-rows items-center space-x-2 text-white" : "flex flex-rows items-center space-x-2 text-white justify-end pr-12"}`}
          >
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <Link
              to="projects"
              className={`${!navVisible ? "block mt-4 lg:inline-block lg:mt-0 text-white mr-4" : "block mt-4 lg:inline-block lg:mt-0 text-white mr-4 justify-end "}`}
            >
              Work
            </Link>
          </div>

          {!navVisible ? (
            <div
              id="mega-menu"
              className={`flex items-center space-x-2 flex-rows text-white  
          `}
              onClick={() => setIsOpen((prev) => !prev)}
            >
              <span className="ring-1 p-0.5 ring-white rounded-full"></span>
              <div className="block mt-4 lg:inline-block lg:mt-0 mr-4 cursor-pointer">
                Effeciencies
              </div>
              <svg
                xmlns="http://www.w3.org/2000/svg"
                fill="none"
                viewBox="0 0 24 24"
                strokeWidth={1}
                stroke="currentColor"
                className="w-4 h-4"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M19.5 8.25l-7.5 7.5-7.5-7.5"
                />
              </svg>
            </div>
          ) : (
            <div
              className={`${!navVisible ? "flex flex-rows items-center space-x-2 text-white" : "flex flex-rows items-center space-x-2 text-white justify-end"}`}
            >
              <span className="ring-1 p-0.5 ring-white rounded-full"></span>
              <Link
                to="strategy"
                className="block mt-4 lg:inline-block lg:mt-0 text-white mr-4 justify-end pr-1"
              >
                Effeciencies
              </Link>
            </div>
          )}

          <div
            className={`${!navVisible ? "flex flex-rows items-center space-x-2 text-white" : "flex flex-rows items-center space-x-2 text-white justify-end pr-10"}`}
          >
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <a
              href="about"
              className="block mt-4 lg:inline-block lg:mt-0 text-white mr-4"
            >
              About
            </a>
          </div>
          <div
            className={`${!navVisible ? "flex flex-rows items-center space-x-2 text-white" : "flex flex-rows items-center space-x-2 text-white justify-end pr-7"}`}
          >
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <a
              href="careers"
              className="block mt-4 lg:inline-block lg:mt-0 text-white mr-7"
            >
              Careers
            </a>
          </div>
          <div
            className={`${!navVisible ? "flex flex-rows items-center space-x-2 text-white" : "flex flex-rows items-center space-x-2 text-white justify-end pr-7"}`}
          >
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <a
              href="contact"
              className="block mt-4 lg:inline-block lg:mt-0 text-white mr-4"
            >
              Contact
            </a>
          </div>
        </div>
      </div>

      <MenuDropdown isOpen={isOpen} setIsOpen={setIsOpen} />
      
    </motion.nav>
  );
}

修改方案说明

要实现全屏白色背景的汉堡菜单,需要调整容器结构和样式,核心改动如下:

  • 将移动端菜单从导航栏内部移出,改为全屏固定层,确保背景覆盖整个视口
  • 为菜单层添加白色背景、内边距和阴影,提升视觉层次
  • 统一菜单项的垂直布局,调整文字颜色为深色适配白色背景
  • 优化汉堡按钮的切换状态(添加关闭图标)
  • 修复状态变量拼写错误(setNaVisible → setNavVisible)

修改后的完整代码

import logo from "./favicon.png";
import { motion } from "framer-motion";
import { useInView } from "react-intersection-observer";
import MenuDropdown from "./MenuDropdown";
import { Link } from "react-router-dom";
import { useState } from "react";

export default function Navigation() {
  const [ref, inView] = useInView({ triggerOnce: false });
  const [isOpen, setIsOpen] = useState(false);
  // 修复状态变量拼写错误
  const [navVisible, setNavVisible] = useState(false);

  return (
    <>
      {/* 顶部导航栏 */}
      <motion.nav
        className="flex items-center justify-between flex-wrap px-6 lg:px-12 py-8 max-w-full mx-auto relative z-50"
        ref={ref}
        initial={{ y: -10, opacity: 0 }}
        animate={inView ? { y: 0, opacity: 1 } : {}}
        exit={{ y: -10, opacity: 0 }}
        transition={{ duration: 0.5 }}
      >
        <a
          href="/"
          className="flex flex-row items-center flex-shrink-0 text-white mr-6 lg:pr-16 space-x-2"
        >
          <img src={logo} className="w-8 h-8" alt="Logo"></img>
          <h2 className="font-bold text-2xl tracking-tight">Jibu Labs</h2>
        </a>

        {/* 汉堡按钮(仅移动端显示) */}
        <div id="menu" className="block lg:hidden">
          <button
            className="flex items-center px-3 py-2 border rounded text-slate-200 border-slate-400 duration-100 hover:text-white hover:border-white"
            onClick={() => setNavVisible(!navVisible)}
          >
            {navVisible ? (
              // 关闭图标
              <svg
                className="fill-current h-4 w-4"
                viewBox="0 0 20 20"
                xmlns="http://www.w3.org/2000/svg"
              >
                <title>Close</title>
                <path d="M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z" />
              </svg>
            ) : (
              // 菜单图标
              <svg
                className="fill-current h-3 w-3"
                viewBox="0 0 20 20"
                xmlns="http://www.w3.org/2000/svg"
              >
                <title>Menu</title>
                <path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" />
              </svg>
            )}
          </button>
        </div>

        {/* 桌面端菜单 */}
        <div className="hidden lg:flex flex-none w-6/12 content-right items-center space-x-12 text-sm">
          <div className="flex items-center space-x-2 text-white">
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <Link to="projects" className="text-white">
              Work
            </Link>
          </div>

          <div
            className="flex items-center space-x-2 text-white cursor-pointer"
            onClick={() => setIsOpen((prev) => !prev)}
          >
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <div>Effeciencies</div>
            <svg
              xmlns="http://www.w3.org/2000/svg"
              fill="none"
              viewBox="0 0 24 24"
              strokeWidth={1}
              stroke="currentColor"
              className="w-4 h-4"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M19.5 8.25l-7.5 7.5-7.5-7.5"
              />
            </svg>
          </div>

          <div className="flex items-center space-x-2 text-white">
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <a href="about" className="text-white">
              About
            </a>
          </div>

          <div className="flex items-center space-x-2 text-white">
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <a href="careers" className="text-white">
              Careers
            </a>
          </div>

          <div className="flex items-center space-x-2 text-white">
            <span className="ring-1 p-0.5 ring-white rounded-full"></span>
            <a href="contact" className="text-white">
              Contact
            </a>
          </div>
        </div>

        <MenuDropdown isOpen={isOpen} setIsOpen={setIsOpen} />
      </motion.nav>

      {/* 移动端全屏菜单 */}
      {navVisible && (
        <motion.div
          className="fixed inset-0 bg-white z-40 pt-24 px-6 shadow-lg"
          initial={{ x: "100%" }}
          animate={{ x: 0 }}
          exit={{ x: "100%" }}
          transition={{ duration: 0.3 }}
        >
          <div className="flex flex-col space-y-8 text-lg">
            <div className="flex items-center space-x-3 text-gray-800">
              <span className="ring-1 p-0.5 ring-gray-800 rounded-full"></span>
              <Link to="projects" className="text-gray-800" onClick={() => setNavVisible(false)}>
                Work
              </Link>
            </div>

            <div className="flex items-center space-x-3 text-gray-800">
              <span className="ring-1 p-0.5 ring-gray-800 rounded-full"></span>
              <Link to="strategy" className="text-gray-800" onClick={() => setNavVisible(false)}>
                Effeciencies
              </Link>
            </div>

            <div className="flex items-center space-x-3 text-gray-800">
              <span className="ring-1 p-0.5 ring-gray-800 rounded-full"></span>
              <a href="about" className="text-gray-800" onClick={() => setNavVisible(false)}>
                About
              </a>
            </div>

            <div className="flex items-center space-x-3 text-gray-800">
              <span className="ring-1 p-0.5 ring-gray-800 rounded-full"></span>
              <a href="careers" className="text-gray-800" onClick={() => setNavVisible(false)}>
                Careers
              </a>
            </div>

            <div className="flex items-center space-x-3 text-gray-800">
              <span className="ring-1 p-0.5 ring-gray-800 rounded-full"></span>
              <a href="contact" className="text-gray-800" onClick={() => setNavVisible(false)}>
                Contact
              </a>
            </div>
          </div>
        </motion.div>
      )}
    </>
  );
}

关键改动细节

  1. 分离菜单结构:将桌面端和移动端菜单完全拆分,移动端菜单作为独立的全屏层,使用fixed inset-0实现全屏覆盖
  2. 背景与视觉优化:移动端菜单添加bg-white白色背景,pt-24预留顶部导航栏空间,px-6添加左右内边距
  3. 交互优化:汉堡按钮切换为关闭图标,点击菜单项自动关闭菜单
  4. 样式统一:移动端菜单文字改为text-gray-800深色,适配白色背景,调整间距提升可读性
  5. 修复错误:修正状态变量setNaVisible的拼写错误为setNavVisible,移除不必要的document.getElementById调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:26:59