DEV Community

Cover image for React Navbar Change Background Color on Scroll - React JS - Gatsby
cesaruseche18
cesaruseche18

Posted on

React Navbar Change Background Color on Scroll - React JS - Gatsby

Currently I'm developing a new website for a client that I have that is a travel agency located in Caracas, Venezuela. I'm using GatsbyJS and Strapi CMS to build the website.

On this tutorial I want to explain how to build a React Navbar smooth scroll background and logo change with GatsbyJS.

Prerequisite:

  • Knowledge of useState() React Hooks.
  • Knowledge of useEffect() React Hooks.

Create your Navbar.js Component.

In my case I created a Navbar.js components and a Navbar.css file where all the styles of the Navbar will live.

After you have your component boiler plate ready and Imported the useState and useEffect Hooks, create a state with the first element in my case I called navbar as an initial state having a value of false and the second element as function setNavbar() for updating the state.

Then create a function I called by changeBackground which sets the value of the state navbar to true when we scroll down the page equal to or more than 66px that in my case that is the height of my navbar. This is done with the help of window.scrollY function. I have used this 66px value in accordance with the value of our navbar’s height (66px). Otherwise the state value remains false.

/navbar scroll changeBackground function
  const changeBackground = () => {
    console.log(window.scrollY)
    if (window.scrollY >= 66) {
      setNavbar(true)
    } else {
      setNavbar(false)
    }
  }
Enter fullscreen mode Exit fullscreen mode

To create the rendering of the background color change of the navbar you will have to create a useEffect where you will pass the changeBackground function and an event listener that will be on scroll and passing the changeBackground function, like so.

useEffect(() => {
    changeLogo()
    // adding the event when scroll change Logo
    window.addEventListener("scroll", changeLogo)
  })
Enter fullscreen mode Exit fullscreen mode

Finally you will need to add a conditional statement to your navbar tag className like the following.

 <nav className={navbar ? "navbar active" : "navbar"}>
Enter fullscreen mode Exit fullscreen mode

I hope this helps you, if you want to do the same with your navbar logo you will be able to see it since I'm attaching my whole navbar component down below. Keep coding, keep learning!

import React, { useState, useEffect } from "react"
// importing navbar styles
import "../assets/css/navbar.css"
import logo from "../assets/images/logo.svg"
import logoBlue from "../assets/images/logo-blue.svg"
// responsive menu toggle icon
import { FaAlignRight } from "react-icons/fa"
// all the navbar links coming from the links constants
import pageLinks from "../constants/links"
// Link from gatsby
import { Link } from "gatsby"
const Navbar = () => {
  //navbar scroll when active state
  const [navbar, setNavbar] = useState(false)

  //logo scroll when active
  const [navbarLogo, setNavbarLogo] = useState(logo)

  //navbar scroll changeBackground function
  const changeBackground = () => {
    console.log(window.scrollY)
    if (window.scrollY >= 66) {
      setNavbar(true)
    } else {
      setNavbar(false)
    }
  }

  useEffect(() => {
    changeBackground()
    // adding the event when scroll change background
    window.addEventListener("scroll", changeBackground)
  })

  //logo scroll function
  const changeLogo = () => {
    if (window.scrollY >= 60) {
      setNavbarLogo(logoBlue)
    } else {
      setNavbarLogo(logo)
    }
  }

  useEffect(() => {
    changeLogo()
    // adding the event when scroll change Logo
    window.addEventListener("scroll", changeLogo)
  })

  return (
    <nav className={navbar ? "navbar active" : "navbar"}>
      <div className="nav-center">
        <div className="nav-header">
          <Link to="/">
            <img src={navbarLogo} alt="logo" />
          </Link>
          <button type="button" className="toggle-btn">
            <FaAlignRight />
          </button>
        </div>
        <div className="nav-links">
          {pageLinks.map(links => {
            return (
              <Link key={links.id} to={links.url}>
                {links.text}
              </Link>
            )
          })}
        </div>
      </div>
    </nav>
  )
}

export default Navbar

Enter fullscreen mode Exit fullscreen mode

Follow me on Github & Connect with me on LinkedIn

https://github.com/cesareuseche
https://www.linkedin.com/in/cesar-useche-profile/

Top comments (3)

Collapse
 
bilal1718 profile image
Muhammad Bilal

That was very helpful!

Collapse
 
guilhermemiua profile image
Guilherme Eiti Akita Miua

Thanks!

Collapse
 
mohamed_gt57 profile image
Mohamed Atef

Thank you very much. That was very helpful.