Home > Enterprise >  sticky navbar in React
sticky navbar in React

Time:12-16

I need to bring the sticky header. When the user scrolls I need to add this sticky header. I've kept offset greater than 200 and added the respective css code. While I am debugging the code offset is printing correctly but by scrolled site is not getting appended. Any one can guide me what I am doing wrong. Below I have added both style and logic. Thanks in advance!

JSX:

import React, { useState, useEffect } from "react"
import "../styles/global.css"

export default function Navbar() {
  const [scrolled, setScrolled] = useState(false)

  const handleScroll = () => {
    const offset = window.scrollY
    console.log("OFFSET VALUE", offset)
    if (offset > 200) {
      setScrolled(true)
    } else {
      setScrolled(false)
    }
  }

  useEffect(() => {
    window.addEventListener("scroll", handleScroll)
  })

  let x = ["site-header"]

  if (scrolled) {
    x.push("scrolled")
  }

  return (
    <>
      <header className={x.join("")}>
        <div className="wrapper site-header__wrapper">
          <h2 className="brand">Community Site</h2>
          <nav className="nav">
            <div className="nav__wrapper">
              <Link className="nav__item" to="/Home">
                <h3> Home</h3>
              </Link>
              <Link className="nav__item" to="/Aboutus">
                <h3>What are we</h3>
              </Link>
              <Link className="nav__item " to="/Contactus">
                <h3>Contact Us</h3>
              </Link>
            </div>
          </nav>
        </div>
      </header>
    </>
  )
}

   

 CSS:
    
    .site-header {
      width: 100%;
      max-width: 100%;
      box-sizing: border-box;
      /* position: relative;
      overflow: hidden; */
      padding: 15px 10px;
      background-color: white;
      border: 1px white;
      transition: all 0.12s ease;
    }
    
    .scrolled {
      position: sticky;
      top: 0;
      left: 0;
      background-color: red;
    }
    .site-header__wrapper {
      padding-top: 4rem;
      padding-bottom: 6rem;
    }
    @media (min-width: 600px) {
      .site-header__wrapper {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding-top: 0;
        padding-bottom: 15px;
      }
    }
    @media (min-width: 600px) {
      .nav__wrapper {
        display: flex;
        gap: 12px;
        align-items: center;
        padding-top: 10px;
        padding-bottom: 0;
      }
    }

CodePudding user response:

I ran some tests and I think I know what happen, you have the class x.join("") however I manually added "site-header" and it worked by also adding an inline style

<header
    className={site-header'}
    style={scrolled ? { opacity: "1" } : { opacity: "0" }}
  >

I also modified the site-header by adding position: fixed; top: 0

If you want to achieve the same result by just adding the class, I recommend you to use properties like opacity or transform: translateY() and add some transition to it

CodePudding user response:

You can try this code.

const [scrolling, setScrolling] = useState(false);
  const [scrollTop, setScrollTop] = useState(0);
  useEffect(() => {
    const onScroll = (e) => {
      setScrollTop(e.target.documentElement.scrollTop);
      if(scrollTop > 200) {
        setScrolling(true)
      };
    };
    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll);
  }, [scrollTop, scrolling]);
  • Related