skip to Main Content

I made a navbar using react/next.js, and I only want to show it when the user is scrolling. If anyone can help, I would greatly appreciate it. Below is my following code for the navbar:

export default function Navbar() {
  const [stickyClass, setStickyClass] = useState('relative');
  const [open, setOpen] = useState(false)

  useEffect(() => {
    window.addEventListener('scroll', stickNavbar);

    return () => {
      window.removeEventListener('scroll', stickNavbar);
    };
  }, []);

  const stickNavbar = () => {
    if (window !== undefined) {
      let windowHeight = window.scrollY;
      windowHeight > 300 ? setStickyClass('fixed top-0 left-1/2 transform -translate-x-1/2 z-50 px-6 py-4 mt-8 border border-border w-96 bg-nav rounded-full') : setStickyClass('relative');
    }
  };

  return (
    <>
      <nav className='top-0 left-0 items-center justify-between w-full p-8 mv:hidden md:flex'>
        <div className='flex items-center cursor-pointer'>
          <Image className='w-6 h-6' src={home} alt='home icon' />
          <span className='text-paragraph font-poppins ml-2 hover:text-theme transition duration-150 ease-in'>Hogwarts</span>
        </div>
        <div className={`flex items-center text-paragraph w-72 justify-between font-poppins cursor-pointer ${stickyClass}`}>
          <Link href="#projects" className='hover:text-theme transition duration-150 ease-in'>Projects</Link>
          <span className='hover:text-theme transition duration-150 ease-in'>About</span>
          <span className='hover:text-theme transition duration-150 ease-in'>Writing</span>
          <span className='hover:text-theme transition duration-150 ease-in'>Tools</span>
        </div>
        <button className='bg-button p-3 rounded-full text-header text-sm border border-border shadow-btn font-poppins tracking-wide '>
          Contact
        </button>
      </nav>
      <MobileButton open={open} setOpen={setOpen} />
      <MobileMenu open={open} setOpen={setOpen} />
    </>
  )
}

2

Answers


  1. You need to calculate the navHeight and then apply the sticky class there.
    Here is a probable implementation.

    export default function Navbar() {
      const [stickyClass, setStickyClass] = useState('relative');
      const [open, setOpen] = useState(false)
      const navRef = useRef(null);
    
      useEffect(() => {
        window.addEventListener('scroll', stickNavbar);
    
        return () => {
          window.removeEventListener('scroll', stickNavbar);
        };
      }, []);
    
      const stickNavbar = () => {
        if (window !== undefined) {
          let windowHeight = window.scrollY;
          let navHeight = navRef.current.offsetHeight;
    
          windowHeight > navHeight ? setStickyClass('fixed top-0 left-1/2 transform -translate-x-1/2 z-50 px-6 py-4 mt-8 border border-border w-96 bg-nav rounded-full') : setStickyClass('relative');
        }
      };
    
      return (
        <>
          <nav ref={navRef} className='top-0 left-0 items-center justify-between w-full p-8 mv:hidden md:flex'>
            <div className='flex items-center cursor-pointer'>
              <Image className='w-6 h-6' src={home} alt='home icon' />
              <span className='text-paragraph font-poppins ml-2 hover:text-theme transition duration-150 ease-in'>Hogwarts</span>
            </div>
            <div className={`flex items-center text-paragraph w-72 justify-between font-poppins cursor-pointer ${stickyClass}`}>
              <Link href="#projects" className='hover:text-theme transition duration-150 ease-in'>Projects</Link>
              <span className='hover:text-theme transition duration-150 ease-in'>About</span>
              <span className='hover:text-theme transition duration-150 ease-in'>Writing</span>
              <span className='hover:text-theme transition duration-150 ease-in'>Tools</span>
            </div>
            <button className='bg-button p-3 rounded-full text-header text-sm border border-border shadow-btn font-poppins tracking-wide '>
              Contact
            </button>
          </nav>
          <MobileButton open={open} setOpen={setOpen} />
          <MobileMenu open={open} setOpen={setOpen} />
        </>
      )
    }
    
    Login or Signup to reply.
  2. try with below,

    import React, { useState, useEffect } from "react";
    import { useWindowScroll } from "react-use";
    
    export default function Navbar() {
      const [stickyClass, setStickyClass] = useState("relative");
      const [open, setOpen] = useState(false);
      const { scrollY } = useWindowScroll();
    
      useEffect(() => {
        window.addEventListener("scroll", stickNavbar);
    
        return () => {
          window.removeEventListener("scroll", stickNavbar);
        };
      }, []);
    
      const stickNavbar = () => {
        if (scrollY > 300) {
          setStickyClass("fixed top-0 left-1/2 transform -translate-x-1/2 z-50 px-6 py-4 mt-8 border border-border w-96 bg-nav rounded-full");
        } else {
          setStickyClass("relative");
        }
      };
    
      return (
        <>
          <nav className={`top-0 left-0 items-center justify-between w-full p-8 mv:hidden md:flex ${stickyClass}`}>
            <div className='flex items-center cursor-pointer'>
              <Image className='w-6 h-6' src={home} alt='home icon' />
              <span className='text-paragraph font-poppins ml-2 hover:text-theme transition duration-150 ease-in'>Hogwarts</span>
            </div>
            <div className='flex items-center text-paragraph w-72 justify-between font-poppins cursor-pointer'>
              <Link href="#projects" className='hover:text-theme transition duration-150 ease-in'>Projects</Link>
              <span className='hover:text-theme transition duration-150 ease-in'>About</span>
              <span className='hover:text-theme transition duration-150 ease-in'>Writing</span>
              <span className='hover:text-theme transition duration-150 ease-in'>Tools</span>
            </div>
            <button className='bg-button p-3 rounded-full text-header text-sm border border-border shadow-btn font-poppins tracking-wide '>
              Contact
            </button>
          </nav>
          <MobileButton open={open} setOpen={setOpen} />
          <MobileMenu open={open} setOpen={setOpen} />
        </>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search