Profile avatar

Chizi Victor

Software Engineer

Toggle Nav on scroll

Hide Nav on scroll down and show on scroll up

Declare a state variable to store the last scroll position of the page.

const [lastScrollY, setLastScrollY] = useState(0);

Then declare a reference to the nav header element with useRef.

const navRef = useRef<HTMLElement | null>(null);

return (
  <header ref={navRef} className='nav'>
    ...
  </header>
)

The controlNavbar function contains the logic to toggle the nav--hidden class on the navbar element. Then wire it up on component mount using useEffect.

const controlNavbar = useCallback(() => {
  const navbar = navRef.current;

  if (typeof window !== 'undefined') {
    if (window.scrollY > lastScrollY) {
      // on scroll down, hide the navbar
      navbar?.classList.add('nav--hidden');
    } else {
      // on scroll up, show the navbar
      navbar?.classList.remove('nav--hidden');
    }

    // persist current page location to use in the next move
    setLastScrollY(window.scrollY);
  }
}, [lastScrollY]);

useEffect(() => {
  if (typeof window === 'undefined') {
    return;
  }

  window.addEventListener('scroll', controlNavbar);

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

SCSS for the .nav-hidden class

.nav {
  ...
  transition: transform 0.4s cubic-bezier(0.075, 0.82, 0.165, 1);

  &.nav--hidden {
    transform: translateY(-100%);
    transition-delay: 0.5s;
  }
}