如何在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> )} </> ); }
关键改动细节
- 分离菜单结构:将桌面端和移动端菜单完全拆分,移动端菜单作为独立的全屏层,使用
fixed inset-0实现全屏覆盖 - 背景与视觉优化:移动端菜单添加
bg-white白色背景,pt-24预留顶部导航栏空间,px-6添加左右内边距 - 交互优化:汉堡按钮切换为关闭图标,点击菜单项自动关闭菜单
- 样式统一:移动端菜单文字改为
text-gray-800深色,适配白色背景,调整间距提升可读性 - 修复错误:修正状态变量
setNaVisible的拼写错误为setNavVisible,移除不必要的document.getElementById调用
内容的提问来源于stack exchange,提问作者Suraya
相关产品推荐
相关产品推荐

