스크롤 시 색상이 바뀌는 헤더 만들기

Som·2023년 4월 18일
0
post-thumbnail

1. 결과물

스크롤바의 위치에 따라 배경 및 아이콘 색상이 바뀌는 헤더를 만들었다.
(gif가 계속 올라가지 않아서, 캡쳐로 대신했다ㅠㅠ)

2. 과정

배경색 외에도 아이콘 색이 바뀌지만, 여기서는 배경색만 바꾸는 법을 작성한다. 아이콘도 같은 원리로 fill 색상만 변경해주면 된다.

// Header.tsx

import { useState, useEffect } from "react";


// styles
import {
  HeaderContainer,
} from "./styles";

const Header = () => {
  const navigate = useNavigate();
  let currentUrl = window.location.pathname;

  const [scrollPosition, setScrollPosition] = useState(0);
  const [headerColor, setHeaderColor] = useState("#ffffff");
  
  // Scroll 위치를 감지
  const updateScroll = () => {
    setScrollPosition(window.scrollY || document.documentElement.scrollTop);
  };

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

    // scroll 위치가 100이하라면 투명한 배경색을 지정하고, 아니면 흰색을 지정한다.
  useEffect(() => {
    if (currentUrl === "/" && scrollPosition < 100) {
      setHeaderColor("transparent"); 
    } else {
      setHeaderColor("#ffffff"); 
    }
  }, [scrollPosition, currentUrl]);

 

  return (
    <HeaderFont>
      <HeaderContainer headercolor={headerColor}>
    	// ... 중략
      </HeaderContainer>
    </HeaderFont>
  );
};

export default Header;
// style.ts

import styled, { css } from "styled-components";

import { mainColor, blue, grey, white, black } from "../../../styles/Colors";


// header.tsx에서 내려준 headercolor를 props으로 받아 배경색을 지정한다.
// 자연스럽게 색상이 바뀌도록 transition 설정을 넣었다.
export const HeaderContainer = styled.div<{ headercolor: string }>`
  display: grid;
  grid-template-columns: 1fr 6fr 1fr;

  position: fixed;
  top: 0;
  width: 100vw;
  height: 60px;
  z-index: 99999;

  background-color: ${(props) => props.headercolor};
  transition: background-color 0.2s ease-out;
  box-shadow: ${(props) =>
    props.headercolor !== "transparent"
      ? "0 2px 8px rgba(0, 0, 0, 0.1)"
      : "none"};
`;

3. 기타

위처럼 styled-component에 prop으로 속성을 내려줄 때 몇가지 주의할 사항이 있다.

첫 번째, styled-component에서 prop을 내려줄 때는 "문자열"로 내려준다.
styled-component에서 모든 속성은 "문자열"로 변환되기 때문에, styled-component에서 numberboolean값을 판별할 수 없다.
전달하고 싶다면 .toString() 등의 메서드를 사용해 "true"나 "false"의 문자열 값을 가지고 판별해야한다.

두 번째, styled-component에서 prop을 내려줄 때는 항상 소문자를 사용한다.
prop을 대문자로 내려주게 되면, 해당 prop이 컴포넌트의 HTML 속성이 아니라 React 컴포넌트로 인식되어 전달되어 에러가 발생한다.

profile
궁금한건 못참아

0개의 댓글