skip to Main Content

The header should slide up with some animation and be hidden when scrolling down the page. When scrolling up, the header should slide down and be visible.

When scrolling up the style should be translateY(0) otherwise the DOM element should be translateY(-200px).

Here are some of the elements that I needed for the implementation:

  • The useEffect hook
  • The useRef hook
  • Setting up listeners for the scroll eventwindow.addEventListener(‘scroll’, handleScroll)
  • Removing listeners for the scroll event:window.removeEventListener(‘scroll’, handleScroll)
  • Keeping track of the previous scroll position in a variable

Below is my code, you can also view it here.

App.js

import React, { useEffect, useRef } from "react";
import "./styles.css";
/*import Header from "./components/Header";*/

const Header = () => {
  const navShowHide = useRef(null);

  useEffect(() => {
    const handleScroll = (e) => {
      navShowHide.current;
    };

    window.addEventListener("scroll", handleScroll);

    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return (
    <>
      <div
        style={{
          color: "white",
          padding: 20,
          backgroundColor: "green",
        }}
        className="headershow"
        ref={navShowHide}
      >
        <h1>Header</h1>
      </div>
    </>
  );
};

export default function App() {
  return (
    <>
      <Header />
      <div
        className="App"
        style={{
          height: 2000,
        }}
      >
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </>
  );
}

styles.css

.headershow {
  transform: translateY(0);
}

.headerhide {
  transform: translateY(-100%);
}

2

Answers


  1. I faced two issues with a scroll-based header update:

    • Class Names Not Updating on Scroll
    • Header Moving to the Top of the Page

    This is the updated code

    import React, { useEffect, useState } from "react";
    import "./styles.css";
    
    const Header = () => {
      const [prevScrollY, setPrevScrollY] = useState(0);
      const [headerTransform, setHeaderTransform] = useState("translateY(0)");
    
      useEffect(() => {
        const handleScroll = () => {
          const currentScrollY = window.scrollY;
    
          if (currentScrollY > prevScrollY) 
            setHeaderTransform("translateY(-100%)");
          else 
            setHeaderTransform("translateY(0)");
    
          setPrevScrollY(currentScrollY);
        };
    
        window.addEventListener("scroll", handleScroll);
    
        return () => {
          window.removeEventListener("scroll", handleScroll);
        };
      }, [prevScrollY]);
    
      return (
        <div
          style={{
            color: "white",
            padding: 20,
            backgroundColor: "green",
            transition: "transform 0.3s ease-in-out",
            transform: headerTransform, 
            position: "fixed",
            top: 0,
            width: "100vw",
          }}
        >
          <h1>Header</h1>
        </div>
      );
    };
    
    export default function App() {
      return (
        <>
          <Header />
          <div
            className="App"
            style={{
              height: 2000,
            }}
          >
            <h1>Hello CodeSandbox</h1>
            <h2>Start editing to see some magic happen!</h2>
          </div>
        </>
      );
    }
    
    Login or Signup to reply.
  2. Is this what you wanted to do ?

    const Header = () => {
      const navShowHide = useRef(null);
    
      useEffect(() => {
        const handleScroll = (e) => {
          if (scrollY > 60) {
            navShowHide.current.className = "headerhide";
          } else {
            navShowHide.current.className = "headershow";
          }
        };
    
        window.addEventListener("scroll", handleScroll);
    
        return () => {
          window.removeEventListener("scroll", handleScroll);
        };
      }, []);
    
      return (
        <>
          <div
            style={{
              color: "white",
              padding: 20,
              backgroundColor: "green",
            }}
            className="headershow"
            ref={navShowHide}
          >
            <h1>Header</h1>
          </div>
        </>
      );
    };
    
    .headershow {
      transition: all 300ms;
      transform: translateY(0);
    }
    
    .headerhide {
      transition: all 300ms;
      transform: translateY(-100%);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search