如何解决响应式Navbar移动端下拉菜单导致按钮移位问题
修复移动端导航栏按钮移位问题
问题核心是下拉菜单与按钮处于同一文档流,展开时会挤压按钮位置。通过绝对定位让菜单脱离文档流,即可实现菜单在按钮下方展开且按钮不移位。
修改后的关键代码片段
<div className="relative"> {/* 添加relative作为菜单绝对定位的参照容器 */} <button type='button' onClick={() => setIsOpen(!isOpen)} className='sm:hidden inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white'> <span className='sr-only'>Open main menu</span> {isOpen ? ( <XMarkIcon className="block h-6 w-6 " aria-hidden="true" /> ) : ( <Bars3Icon className="block h-6 w-6" aria-hidden="true" /> )} </button> {isOpen && ( {/* 用绝对定位让菜单脱离文档流,在按钮下方靠右展开 */} <div className='absolute right-0 top-full mt-2 space-y-1 px-2 pb-3 pt-2 w-48 bg-gray-800 rounded-md'> <div className='rounded-md ring-1 ring-black ring-opacity-5 overflow-hidden'> {menu_list.map((item) => ( <Link href={item.href} key={item.name} className={classNames( item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'block px-4 py-2 text-sm' )} aria-current={item.current ? 'page' : undefined} > {item.name} </Link> ))} </div> </div> )} </div>
完整修改后的Navbar2.jsx代码
'use client'; import Link from 'next/link'; import Image from 'next/image'; import NavItem from './NavItem'; import { motion } from 'framer-motion'; import { navVariants } from '../utils/motion'; import styles from '../styles'; import { useState } from 'react'; import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'; import { Disclosure, Menu, Transition } from '@headlessui/react'; const menu_list = [ { name: 'Home', href: '/', current: true }, { name: 'About', href: '/', current: false }, { name: 'Contact', href: '/', current: false }, ] function classNames(...classes) { return classes.filter(Boolean).join(' ') } const Navbar2 = () => { const [isOpen, setIsOpen] = useState(false); return( <motion.nav variants={navVariants} initial='hidden' whileInView='show' className={`${styles.xPaddings} py-8 relative z-30`} > <div className='absolute w-[50%] inset-0 gradient-01' /> <div className={`${styles.innerWidth} mx-auto flex justify-between gap-8`}> <Link href='/' className='z-30 opacity-50 hover:opacity-100'> <Image src='/headset.svg' alt='logo' width={30} height={30} className='object-contain' /> </Link> <h2 className='font-extrabold text-[24px] leading-[30px] text-white'> TITLE </h2> <div className='hidden sm:flex space-x-4'> {menu_list.map((item) => ( <Link href={item.href} className={classNames( item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'rounded-md px-3 py-2 text-sm font-medium' )} aria-current={item.current ? 'page' : undefined} > {item.name} </Link> ))} </div> <div className="relative"> <button type='button' onClick={() => setIsOpen(!isOpen)} className='sm:hidden inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white'> <span className='sr-only'>Open main menu</span> {isOpen ? ( <XMarkIcon className="block h-6 w-6 " aria-hidden="true" /> ) : ( <Bars3Icon className="block h-6 w-6" aria-hidden="true" /> )} </button> {isOpen && ( <div className='absolute right-0 top-full mt-2 space-y-1 px-2 pb-3 pt-2 w-48 bg-gray-800 rounded-md'> <div className='rounded-md ring-1 ring-black ring-opacity-5 overflow-hidden'> {menu_list.map((item) => ( <Link href={item.href} key={item.name} className={classNames( item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'block px-4 py-2 text-sm' )} aria-current={item.current ? 'page' : undefined} > {item.name} </Link> ))} </div> </div> )} </div> </div> </motion.nav> ) } export default Navbar2;
修改说明
relative:给按钮外层容器添加相对定位,让内部绝对定位的菜单以此为参照点absolute right-0 top-full mt-2:让菜单脱离文档流,靠右对齐按钮底部并保留小间距,彻底避免挤压按钮w-48 bg-gray-800:固定菜单宽度并添加背景,提升移动端菜单的可读性和美观度
内容的提问来源于stack exchange,提问作者Mitch
相关产品推荐
相关产品推荐

