DEV Community

Muhammad Bilal Mohib-ul-Nabi
Muhammad Bilal Mohib-ul-Nabi

Posted on

How to change navbar style on scroll in React JS/Next JS

Today I am going to tell you one of the simplest ways to change the navbar styling on scroll.So first of all.Lets create a component Header.I am pasting the bootstrap simple code for Header just to keep things as simple as I can.To use the html css of bootstrap we have to first convert it in jsx which you can easily do by going to this website.

htmltojsx
Simply paste the code copied from bootstrap navbar and paste it on this website.It will return you with jsx code.
Header.jsx

 <nav className="navbar navbar-expand-lg navbar-light bg-light">
        <a className="navbar-brand" href="#">Navbar</a>
        <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span className="navbar-toggler-icon" />
        </button>
        <div className="collapse navbar-collapse" id="navbarSupportedContent">
          <ul className="navbar-nav mr-auto">
            <li className="nav-item active">
              <a className="nav-link" href="#">Home <span className="sr-only">(current)</span></a>
            </li>
            <li className="nav-item">
              <a className="nav-link" href="#">Link</a>
            </li>
            <li className="nav-item dropdown">
              <a className="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                Dropdown
              </a>
              <div className="dropdown-menu" aria-labelledby="navbarDropdown">
                <a className="dropdown-item" href="#">Action</a>
                <a className="dropdown-item" href="#">Another action</a>
                <div className="dropdown-divider" />
                <a className="dropdown-item" href="#">Something else here</a>
              </div>
            </li>
            <li className="nav-item">
              <a className="nav-link disabled" href="#">Disabled</a>
            </li>
          </ul>
          <form className="form-inline my-2 my-lg-0">
            <input className="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" />
            <button className="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
          </form>
        </div>
      </nav>
Enter fullscreen mode Exit fullscreen mode

and its css will be

Header.css

.navbar {
    background-color: #a8dcef;
    height: 105px;
    width: 100%;
    position: fixed;
    z-index: 1000;
    border-bottom: 1px solid rgb(192, 192, 192);
}

Enter fullscreen mode Exit fullscreen mode

Now we will use useEffect hook to

  • Read the scroll position and store it in the data attribute.
  • Listen for new scroll events.
  • Update scroll position.

So this is the code you have to paste it in useEffect hook in Header.jsx

useEffect(() => {
        // The debounce function receives our function as a parameter
        const debounce = (fn) => {
            // This holds the requestAnimationFrame reference, so we can cancel it if we wish
            let frame;
            // The debounce function returns a new function that can receive a variable number of arguments
            return (...params) => {
                // If the frame variable has been defined, clear it now, and queue for next frame
                if (frame) {
                    cancelAnimationFrame(frame);
                }
                // Queue our function call for the next frame
                frame = requestAnimationFrame(() => {
                    // Call our function and pass any params we received
                    fn(...params);
                });
            }
        };

        // Reads out the scroll position and stores it in the data attribute
        // so we can use it in our stylesheets
        const storeScroll = () => {
            document.documentElement.dataset.scroll = window.scrollY;
        }

        // Listen for new scroll events, here we debounce our `storeScroll` function
        document.addEventListener('scroll', debounce(storeScroll), { passive: true });

        // Update scroll position for first time
        storeScroll();
    })
Enter fullscreen mode Exit fullscreen mode

Now Last Step.For changing the styling we can use this css.In Header.css

html:not([data-scroll="0"]) .navbar {
    position: fixed;
    top: 0;
    width: 100%;
    /* background-color: #fff; */
    opacity: 0.9;
    box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.5);
    transition: 0.4s linear;
}
Enter fullscreen mode Exit fullscreen mode

Note:-

And thats it.Now you will see a change when you scroll down.

This format can be used to change any class on scroll the format is

html:not([data-scroll="0"]) .Here Class name {
    /* Write the code you want to change */
}
Enter fullscreen mode Exit fullscreen mode

Share it if you found it helpful!
Let me know in the comments if you find any difficulty.I will be there to help you.
Thanks.

Discussion (4)

Collapse
rehanjvd profile image
Rehan javed

MASHAALLAH bro

Collapse
bilalmohib profile image
Muhammad Bilal Mohib-ul-Nabi Author

Jazaka Allah

Collapse
rehanjvd profile image
Rehan javed

brother can we connect on whatsapp? this is my whatsapp 00447849537251

Thread Thread
bilalmohib profile image
Muhammad Bilal Mohib-ul-Nabi Author

Sure