Animated Sticky Navbar with Tailwind CSS and React
When the navbar becomes sticy show like an animation that navbar is coming from top to bottomimport React, { useState, useEffect } from "react"; import { FaHome, FaUserAlt, FaCog, FaPhone, FaStar, FaBars, FaTimes, FaChevronDown, } from "react icons/fa"; import { GiCrystalBall } from "react icons/gi"; const Navbar = () => { const [isOpen, setIsOpen] = useState(false); const [isSticky, setIsSticky] = useState(false); const [activeDropdown, setActiveDropdown] = useState(null); useEffect(() => { const handleScroll = () => { setIsSticky(window.scrollY > 0); }; window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); const services = [ "Tarot Reading", "Crystal Healing", "Spiritual Guidance", "Aura Reading", ]; const testimonials = [ "Client Stories", "Video Reviews", "Written Feedback", "Success Stories", ]; const handleDropdown = (menu) => { setActiveDropdown(activeDropdown === menu ? null : menu); }; return ( <nav className={`w full ${ isSticky ? "fixed top 0 shadow lg bg [#576d9c]/95" : "bg [#576d9c]" } transition all duration 300 ease in out z 50`} role="navigation" aria label="Main navigation" > <div className="max w 7xl mx auto px 4 sm:px 6 lg:px 8"> <div className="flex items center justify between h 20"> <div className="flex shrink 0 flex items center"> <GiCrystalBall className="h 12 w 12 text white hover:text gray 200 transition colors duration 300 animate pulse" aria label="Mystic Readings Logo" /> <span className="ml 3 text 2xl font mystical text white hover:scale 105 transition transform duration 300"> Mystic Readings </span> </div> {/* Desktop Navigation */} <div className="hidden md:flex items center space x 8"> <a href="#" className="nav link flex items center group" aria label="Home" > <FaHome className="mr 2 group hover:rotate 12 transition transform duration 300" /> <span>Home</span> </a> <a href="#" className="nav link flex items center group" aria label="About Us" > <FaUserAlt className="mr 2 group hover:scale 110 transition transform duration 300" /> <span>About Us</span> </a> <div className="relative"> <button className="nav link flex items center group" onClick={() => handleDropdown("services")} aria expanded={activeDropdown === "services"} aria haspopup="true" > <FaCog className="mr 2 group hover:rotate 90 transition transform duration 300" /> <span>Services</span> <FaChevronDown className={`ml 2 transition transform duration 300 ${ activeDropdown === "services" ? "rotate 180" : "" }`} /> </button> {activeDropdown === "services" && ( <div className="dropdown menu animate fadeIn"> {services.map((service, index) => ( <a key={index} href="#" className="block px 4 py 2 text white hover:bg [#435580] transition colors duration 200 hover:translate x 2 transform" > {service} </a> ))} </div> )} </div> <a href="#" className="nav link flex items center group" aria label="Contact Us" > <FaPhone className="mr 2 group hover:rotate 12 transition transform duration 300" /> <span>Contact Us</span> </a> <div className="relative"> <button className="nav link flex items center group" onClick={() => handleDropdown("testimonials")} aria expanded={activeDropdown === "testimonials"} aria haspopup="true" > <FaStar className="mr 2 group hover:scale 110 transition transform duration 300" /> <span>Testimonials</span> <FaChevronDown className={`ml 2 transition transform duration 300 ${ activeDropdown === "testimonials" ? "rotate 180" : "" }`} /> </button> {activeDropdown === "testimonials" && ( <div className="dropdown menu animate fadeIn"> {testimonials.map((testimonial, index) => ( <a key={index} href="#" className="block px 4 py 2 text white hover:bg [#435580] transition colors duration 200 hover:translate x 2 transform" > {testimonial} </a> ))} </div> )} </div> </div> {/* Mobile Navigation Button */} <button className="md:hidden text white hover:text gray 200 focus:outline none focus:ring 2 focus:ring white transform hover:scale 110 transition transform duration 300" onClick={() => setIsOpen(!isOpen)} aria expanded={isOpen} aria label="Toggle navigation menu" > {isOpen ? ( <FaTimes className="h 6 w 6 animate spin slow" /> ) : ( <FaBars className="h 6 w 6 hover:rotate 180 transition transform duration 500" /> )} </button> </div> </div> {/* Mobile Navigation Menu */} {isOpen && ( <div className="md:hidden bg [#435580] shadow lg animate slideDown"> <div className="px 2 pt 2 pb 3 space y 1"> <a href="#" className="mobile nav link hover:translate x 2 transform transition transform duration 200" > <FaHome className="mr 2" /> Home </a> <a href="#" className="mobile nav link hover:translate x 2 transform transition transform duration 200" > <FaUserAlt className="mr 2" /> About Us </a> <button className="w full mobile nav link text left hover:translate x 2 transform transition transform duration 200" onClick={() => handleDropdown("services")} > <FaCog className="mr 2" /> Services{" "} <FaChevronDown className={`ml 2 inline transition transform duration 300 ${ activeDropdown === "services" ? "rotate 180" : "" }`} /> </button> {activeDropdown === "services" && ( <div className="pl 4 space y 1 animate fadeIn"> {services.map((service, index) => ( <a key={index} href="#" className="mobile nav link hover:translate x 4 transform transition transform duration 200" > {service} </a> ))} </div> )} <a href="#" className="mobile nav link hover:translate x 2 transform transition transform duration 200" > <FaPhone className="mr 2" /> Contact Us </a> <button className="w full mobile nav link text left hover:translate x 2 transform transition transform duration 200" onClick={() => handleDropdown("testimonials")} > <FaStar className="mr 2" /> Testimonials{" "} <FaChevronDown className={`ml 2 inline transition transform duration 300 ${ activeDropdown === "testimonials" ? "rotate 180" : "" }`} /> </button> {activeDropdown === "testimonials" && ( <div className="pl 4 space y 1 animate fadeIn"> {testimonials.map((testimonial, index) => ( <a key={index} href="#" className="mobile nav link hover:translate x 4 transform transition transform duration 200" > {testimonial} </a> ))} </div> )} </div> </div> )} <style jsx>{` .nav link { @apply text white hover:text gray 200 px 3 py 2 rounded md text sm font medium transition colors duration 200 focus:outline none focus:ring 2 focus:ring white flex items center; } .mobile nav link { @apply flex items center text white hover:bg [#2c3a57] hover:text gray 200 px 3 py 2 rounded md text base font medium transition colors duration 200; } .dropdown menu { @apply absolute right 0 mt 2 w 48 rounded md shadow lg bg [#435580] ring 1 ring black ring opacity 5 divide y divide [#2c3a57] focus:outline none transform opacity 100 scale 100 transition ease out duration 200; } .font mystical { font family: "Cinzel", serif; } @keyframes fadeIn { from { opacity: 0; transform: translateY( 10px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideDown { from { opacity: 0; transform: translateY( 20px); } to { opacity: 1; transform: translateY(0); } } @keyframes spin slow { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .animate fadeIn { animation: fadeIn 0.3s ease out; } .animate slideDown { animation: slideDown 0.3s ease out; } .animate spin slow { animation: spin slow 0.8s linear; } `}</style> </nav> ); }; export default Navbar;
