Add blur effect to navigation scroll bar

Issue

I am trying to implement a navbar that has a blur effect when scrolling.
This works, but when I refresh the page, the scrollbar stays in the same position and I don’t get any result from window.pageYOffset. The result of this is that I have a transparent navigation bar.

I’m also using TailwindCSS, but I think this doesn’t matter.

Code example:

import React, { useState, useEffect } from 'react'

const Navigation: React.FC = () => {
  const [top, setTop] = useState(true);

  useEffect(() => {
    const scrollHandler = () => {
      window.pageYOffset > 20 ? setTop(false) : setTop(true)
    };
    window.addEventListener('scroll', scrollHandler);
    return () => {
      window.removeEventListener('scroll', scrollHandler);
    }
  }, [top]);

  return (
    <header className={`fixed w-full z-30 ${!top && 'bg-white dark:bg-black bg-opacity-80 dark:bg-opacity-80 backdrop-blur dark:backdrop-blur'}`}>
    </header>
  );
};

export default Navigation

Solution

You need to explicitly call scrollHandler() inside the useEffect if you want the navbar to keep its blurred state when the page is refreshed.

useEffect(() => {
    const scrollHandler = () => {
        window.pageYOffset > 20 ? setTop(false) : setTop(true)
    };
    window.addEventListener('scroll', scrollHandler);
    scrollHandler(); // Explicit call so that the navbar gets blurred if current page offset is `window.pageYOffset > 20`
    
    return () => {
        window.removeEventListener('scroll', scrollHandler);
    }
}, []);

You can also remove top from the useEffect‘s dependencies array, you only need it to run when the component is mounted.

Answered By – juliomalves

Answer Checked By – David Goodson (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.