Tailwind CSS滚动控制Navbar无法添加过渡动画问题求助
问题原因与解决方案
核心问题
你用了Tailwind的hidden类来隐藏导航栏,但hidden对应CSS的display: none,这个属性无法触发过渡动画——元素会直接消失/出现,没有中间过渡过程,这就是动画不生效的根本原因。
另外代码还有两个小问题:
visable状态切换时重复添加了transition ease-linear duration-700类,属于冗余代码useEffect没有设置依赖数组,会导致滚动事件被重复绑定,影响性能
修复步骤
- 替换
hidden为可过渡的属性:用transform: translateY(-100%)实现隐藏,translateY(0)实现显示 - 简化className逻辑,只在基础类里加一次过渡相关样式
- 给
useEffect添加空依赖数组,确保事件只绑定一次
修改后的完整代码
const Navbar: React.FC = () => { const [isOpen, setIsOpen] = useState(false) const [prevScrollPosition, setPrevScrollPosition] = useState(0) const [visible, setVisible] = useState(true) // 修正拼写:visable → visible const handleScroll = () => { const currentScrollPosition = window.scrollY // 添加滚动阈值,避免小幅度滚动时频繁切换导航栏状态 if (currentScrollPosition > prevScrollPosition + 10) { setVisible(false) } else if (currentScrollPosition < prevScrollPosition - 10) { setVisible(true) } setPrevScrollPosition(currentScrollPosition) } useEffect(() => { window.addEventListener("scroll", handleScroll) return () => window.removeEventListener("scroll", handleScroll) }, []) // 添加空依赖数组,避免重复绑定事件 return ( <> <nav className={`transition-all duration-700 ease-linear border-gray-900 bg-gray-50 flex border-b w-full fixed z-50 ${ visible ? "translate-y-0" : "-translate-y-full" }`} > <div className="flex-1 flex justify-center mr-auto py-3 px-10"> <button onClick={() => setIsOpen((prev) => !prev)} type="button" className="flex-1 space-y-1.5 " > <Bars4Icon className="h-10 w-10 transition-all hover:scale-125 duration-300 hover:text-indigo-800" /> </button> {isOpen && ( <div className="w-full h-screen top-0 z-30 bg-black bg-opacity-60 absolute"> <div className="text-indigo-900 h-screen bg-gray-50 absolute z-40 w-2/6 py-3 px-10 top-0 left-0"> <XMarkIcon onClick={() => setIsOpen((prev) => !prev)} className="h-12 w-12 mb-10 cursor-pointer hover:scale-125 transition-all duration-300" /> <ul className="flex flex-col mb-10 gap-10 text-4xl font-thin"> <li onClick={(e) => (window.location.href = "/")} className="cursor-pointer hover:scale-105 hover:pl-10 transition-all duration-300" > Home </li> <li onClick={(e) => (window.location.href = "/offer")} className="cursor-pointer hover:scale-110 hover:pl-10 duration-300" > Offer </li> <li className="hover:scale-110 hover:pl-10 duration-300"> Contact </li> <li className="hover:scale-110 hover:pl-10 duration-300"> Team </li> </ul> </div> </div> )} <div className="mx-36 invisible lg:visible transition-all hover:scale-110 duration-500"> <button onClick={(e) => (window.location.href = "/")}> <img src={logo} className="h-9" alt="Logo" /> </button> </div> <span onClick={(e) => (window.location.href = "/offer")} className="flex flex-1 cursor-pointer transition-all duration-500 transform hover:text-indigo-800 justify-end ml-auto decoration-indigo-800 hover:text-2xl underline-offset-8 underline text-xl font-light whitespace-nowrap" > How it works ? </span> </div> </nav> </> ) } export default Navbar
额外优化说明
- 修正了
visable的拼写错误为visible(符合代码规范) - 添加滚动阈值(±10),防止滚动时微小位置变化导致导航栏频繁切换
- 用
transition-all替代重复的过渡类,代码更简洁
内容的提问来源于stack exchange,提问作者DrSpliff
相关产品推荐
相关产品推荐

