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

React结合Tailwindcss实现移动端导航栏显隐过渡效果

实现方案

你当前技术栈已经包含Headless UI,直接使用其内置的Transition组件实现过渡动画是成本最低、适配性最好的方案,不需要额外引入第三方动画库。该组件会自动在元素离场时等待动画执行完成再卸载DOM节点,完美解决你当前直接条件渲染无动画的问题。


实现步骤

1. 修改Navbar组件

首先从Headless UI引入Transition组件,将原有的条件渲染逻辑替换为Transition包裹结构,配置Tailwind过渡类实现「下滑+淡入」的常规移动端导航动画效果:

import { useState } from 'react';
import { Transition } from '@headlessui/react';
import { FiMenu } from 'react-icons/fi';
import MobileMenu from './MobileMenu';

function Navbar() {
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  return (
    <>
      <nav className="flex justify-between items-center px-4 lg:px-8 py-3 bg-gray-900 text-white">
        {/* Mobile Menu Icon */}
        <div
          className="block md:hidden p-2 cursor-pointer rounded-full hover:bg-gray-700 transition duration-200"
          onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
        >
          <FiMenu size={20} />
        </div>
      </nav>
      {/* 带动画的移动端菜单 */}
      <Transition
        show={mobileMenuOpen}
        unmount={true}
        enter="transition duration-200 ease-out"
        enterFrom="opacity-0 -translate-y-2"
        enterTo="opacity-100 translate-y-0"
        leave="transition duration-150 ease-in"
        leaveFrom="opacity-100 translate-y-0"
        leaveTo="opacity-0 -translate-y-2"
      >
        <MobileMenu />
      </Transition>
    </>
  );
}

export default Navbar;

注:原代码中transition-2为无效类名,已替换为标准Tailwind类transition duration-200实现按钮hover的平滑过渡。

2. (可选)增加菜单项错落动画

如果想要菜单内的导航项依次出现的错落效果,可以在MobileMenu中使用Transition.Child组件,给每个子项设置不同的延迟时间即可,修改后的MobileMenu代码如下:

import { Transition } from '@headlessui/react';
import { ImHome } from 'react-icons/im';
import { HiUsers } from 'react-icons/hi';
import { CgProfile } from 'react-icons/cg';

function MobileMenu() {
  return (
    <div className="block md:hidden px-4 py-3 text-white w-full bg-gray-800 border-t border-opacity-70 border-slate-700">
      <Transition.Child
        enter="transition duration-200 ease-out delay-100"
        enterFrom="opacity-0 translate-x-[-10px]"
        enterTo="opacity-100 translate-x-0"
        leave="transition duration-100 ease-in"
        leaveFrom="opacity-100 translate-x-0"
        leaveTo="opacity-0 translate-x-[-10px]"
      >
        <div className="flex items-center mb-3 pb-3 border-b border-slate-700">
          <img
            src="https://africaprime.com/wp-content/uploads/2020/04/ElonMusk.jpg"
            className="rounded-full w-8 h-8 cursor-pointer"
          />
          <h6 className="ml-5 cursor-pointer">Elon Musk</h6>
        </div>
      </Transition.Child>
      <Transition.Child
        enter="transition duration-200 ease-out delay-150"
        enterFrom="opacity-0 translate-x-[-10px]"
        enterTo="opacity-100 translate-x-0"
        leave="transition duration-100 ease-in delay-50"
        leaveFrom="opacity-100 translate-x-0"
        leaveTo="opacity-0 translate-x-[-10px]"
      >
        <div className="mobile-nav-icon flex items-center py-2">
          <ImHome size={20} />
          <h4 className="ml-5">Home</h4>
        </div>
      </Transition.Child>
      <Transition.Child
        enter="transition duration-200 ease-out delay-200"
        enterFrom="opacity-0 translate-x-[-10px]"
        enterTo="opacity-100 translate-x-0"
        leave="transition duration-100 ease-in"
        leaveFrom="opacity-100 translate-x-0"
        leaveTo="opacity-0 translate-x-[-10px]"
      >
        <div className="mobile-nav-icon flex items-center py-2">
          <HiUsers size={20} />
          <h4 className="ml-5">Friends</h4>
        </div>
      </Transition.Child>
      <Transition.Child
        enter="transition duration-200 ease-out delay-250"
        enterFrom="opacity-0 translate-x-[-10px]"
        enterTo="opacity-100 translate-x-0"
        leave="transition duration-100 ease-in"
        leaveFrom="opacity-100 translate-x-0"
        leaveTo="opacity-0 translate-x-[-10px]"
      >
        <div className="mobile-nav-icon flex items-center py-2">
          <CgProfile size={20} />
          <h4 className="ml-5">My Profile</h4>
        </div>
      </Transition.Child>
    </div>
  );
}

export default MobileMenu;

小提示:原代码中mobile-nav-icon类缺少flex布局,图标和文字无法对齐,已补充flex items-center py-2优化点击区域和排版。


动画参数调整说明

你可以根据自己的设计需求修改对应类名调整动画效果:

  • 调整duration-200/duration-150的数值可以修改动画快慢
  • 把-translate-y-2换成-translate-y-full可以实现整屏从上滑入的效果
  • 修改delay-*的数值可以调整菜单项错落动画的间隔时间
  • 替换ease函数(比如ease-in-out)可以修改动画的加速度曲线

内容的提问来源于stack exchange,提问作者M7md-Dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:33:38