ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [react][typeScript][styled-component] hover시 svg 이미지 색깔 바꾸기
    프론트엔드 개발자가 될거야./css 라이브러리 2023. 2. 8. 15:32

    이미지는 png, jpg, svg 등 여러 확장자를 가진다. 

    나는 그동안 png를 많이 썼는데

    header의 icon 이미지를 hover 했을 때 hover 이벤트로 색상을 변경해 주어야 할 때

    png를 쓰면 color를 변경할 수 없어서 이미지를 바꿔줘야하는데 이 방법은 매우 비효율적이라는 생각이 들었다.

     

    예를들어 이런 상황이다. 

    바이낸스의 헤더

    그래서 header의 이미지 중 hover 이벤트로 색상을 변경해주어야 하는 이미지는 svg로 바꾸어 주었다.

     

    SVG ?

    • svg 파일은 픽셀로 이루어진 png 파일과는 다르게 라인과 곡선들로 이루어져 있다.
      이런 점에서 파일을 확대하거나 줄였을때 이미지가 깨지지 않고 그대로 선명함을 유지한다.
    • svg 파일은 값을 조작 할 수 있기 때문에
      js를 이용해서 svg 아이콘의 색상을 변경하거나 애니메이션을 적용시킬 수도 있어서
      이미지 파일을 원하는 스타일에 맞게 변경이 가능하다.
    • svg 파일 사이즈는 기본적으로는 작은 편에 속한다.
      그렇지만 이미지가 복잡해질수록 크기가 커지거나 속도 저하를 일으킨다.

    즉, 로고, 아이콘 또는 단순화된 이미지는 svg로 하는 것이 적절하다!

     

     

    styled-component, typeScript에 svg 적용하기

     

    svg의 색상은 path의 fill 속성에 의해 색상이 변경된다.

    우리는 이 fill 속성의 색을 변경시켜주면 된다.

     

    - styled-component

    const SVG = styled.svg<{ isHover: boolean }>`
      fill: ${(props) =>
        props.isHover
          ? 'blue'
          : 'black' };
    
      &:hover {
        fill: 'blue' ;
      }
    `;

    - props 전달

        <li
          onMouseOver={() => setIsHover(true)}
          onFocus={() => setIsHover(true)}
          onMouseOut={() => setIsHover(false)}
          onBlur={() => setIsHover(false)}
        >
          <SVG
            isHover={isHover} // isHover값 전달해주기
            width="16"
            height="16"
            viewBox="0 0 16 16"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
          >
            <g clipPath="url(#clip0_369_6410)">
              <path d="M14.2609 9.3913V14.2609H1.73914V9.3913H0.347839V14.2609V15.6522H1.73914H14.2609H15.6522V14.2609V9.3913H14.2609Z" />
              <path d="M9.39137 0.347824H6.60876V1.73913H9.39137V0.347824Z" />
              <path d="M12.174 7.30434H9.39139V2.43478H6.60878V7.30434H3.82617L8.00008 12.8696L12.174 7.30434Z" />
            </g>
            <defs>
              <clipPath id="clip0_369_6410">
                <rect
                  width="15.3043"
                  height="15.3043"
                  fill="white"
                  transform="translate(0.347839 0.347824)"
                />
              </clipPath>
            </defs>
          </SVG>
        </li>

     

    - 전체코드

    import React, { useState } from "react";
    import styled from "styled-components";
    
    function DownloadLi() {
      const [isHover, setIsHover] = useState(false);
    
      return (
        <li
          onMouseOver={() => setIsHover(true)}
          onFocus={() => setIsHover(true)}
          onMouseOut={() => setIsHover(false)}
          onBlur={() => setIsHover(false)}
        >
          <SVG
            isHover={isHover}
            width="16"
            height="16"
            viewBox="0 0 16 16"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
          >
            <g clipPath="url(#clip0_369_6410)">
              <path d="M14.2609 9.3913V14.2609H1.73914V9.3913H0.347839V14.2609V15.6522H1.73914H14.2609H15.6522V14.2609V9.3913H14.2609Z" />
              <path d="M9.39137 0.347824H6.60876V1.73913H9.39137V0.347824Z" />
              <path d="M12.174 7.30434H9.39139V2.43478H6.60878V7.30434H3.82617L8.00008 12.8696L12.174 7.30434Z" />
            </g>
            <defs>
              <clipPath id="clip0_369_6410">
                <rect
                  width="15.3043"
                  height="15.3043"
                  fill="white"
                  transform="translate(0.347839 0.347824)"
                />
              </clipPath>
            </defs>
          </SVG>
        </li>
      );
    }
    
    export default DownloadLi;
    
    const SVG = styled.svg<{ isHover: boolean }>`
      fill: ${(props) =>
        props.isHover
          ? 'blue'
          : 'black' };
    
      &:hover {
        fill: 'blue' ;
      }
    `;

     

     

    댓글

Designed by Tistory.