[Project] SVG 파일 아이콘 색상 변경하기

SEONDY·2024년 10월 27일

Project

목록 보기
4/9
post-thumbnail

[Project] SVG 파일 아이콘 색상 변경하기

  • 프로젝트를 진행하며, 피그마의 아이콘 파일을 전부 SVG로 export해서 사용했다.
    SVG 파일을 내가 원하는 색상으로 CSS를 활용해 변경하려고 했는데, 그게 마음처럼 되지 않았다...😹
    해커톤 때는, 시간이 부족해서 CSS를 활용해 변경하는 방식은 적용하지 못했고, 디자이너님께 색상 변경을 요청해서 아이콘을 관리했다.
  • 해커톤 이후, 프로젝트를 지속하는 과정에서 해당 부분을 찾아봤다.
    그 이유는, 색상 변경을 하나하나 요청하는 것이 협업 측면에서도 비효율적이었으며, 아이콘 파일을 색상별로 관리하는 것 또한 매우 비효율적이라고 생각했기 때문이다.
  • SVG 파일에 대해 알아본 과정과 해결한 방법을 정리해보려 한다!

🖼️구현 화면

회색으로 변경된 것을 볼 수 있다!

CSS 함수 적용 전CSS 함수 적용 후

1. SVG 파일

SVG 파일은,

  • Scalable Vector Graphics (확장 가능한 벡터 그래픽)
  • 웹 친화적인 벡터 파일 포맷.
    픽셀 기반 래스터 파일(JPEG 등)과 달리, 벡터 파일은 그리드 위의 점과 선을 기반으로 하는 수학 공식을 통해 이미지를 저장한다.
  • SVG는 XML 코드로 작성되어 모든 텍스트 정보를 모양이 아닌 텍스트로 저장한다.
    검색 엔진이 SVG 그래픽을 키워드로 읽을 수 있어, 웹 사이트의 검색 순위를 높이는 데 큰 도움이 된다.

SVG 파일 장단점

  • 장점
    • 크기에 상관없이 항상 해상도를 유지한다. (품질 저하 X)
    • 래스터 이미지보다 크기가 작다.
    • SVG 파일은 텍스트를 디자인이 아닌 텍스트로 처리한다.
      스크린 리더가 SVG 이미지에 포함된 모든 단어를 스캔할 수 있다.
  • 단점
    • 픽셀이 부족하기 때문에 고품질 디지털 사진을 표현하기 어렵다. (디테일이 풍부한 사진에는 JPEG 파일이 더 좋음)
    • SVG 이미지에 포함된 코드를 처음 사용하는 경우 이해하기 힘들 수 있다.

SVG 파일을 열어보면?

사용했던 bookmark_on.svg 파일을 열어보면 그래픽 파일이 아닌, 텍스트로 적혀있는 것을 볼 수 있다.

  • <svg></svg> 태그 안에 표현된다.
  • <g></g> 태그 : 좌표를 보정하는 역할
  • <path/> 태그 : 실제 도형을 그리는 역할

2. SVG 파일 색상 변경하기

2.1. SVG 파일에서 직접 바꾸기

  • SVG 파일 내의 코드를 바꿔서 색상을 변경하는 방법이 있다.
    실제 도형을 그리는 <path /> 태그를 보면, fill 속성이 있다.
    <path d="" fill="green"/>
    이를 변경해주면, 다음과 같이 아이콘의 색상이 변경되는 것을 확인할 수 있다.

  • 이 방법은 결국, 색상 별로 파일을 관리해야 하므로 효율적이지 않았다.
    그런데 지금 생각해보면, svg 파일을 import해서 <g> 태그의 fill 속성을 변경해 준다면? CSS로 충분히 바뀔 것 같기도 하다...

2.2. SVG 파일에 filter 속성 적용

  • 내가 사용한 방법이다. img 태그에 불러온 svg 파일에 CSS로 filter 속성을 적용하는 방법을 생각했다.

applyIconColors 함수

// utils/iconStyles.jsx
/** svg 아이콘 색상 변환 함수 */
export function applyIconColors(color) {
  let iconColor;
  switch (color) {
    case "primary":
      iconColor = "invert(57%) sepia(42%) saturate(4074%) hue-rotate(121deg) brightness(95%) contrast(76%)";
      break;
    case "gray1":
      iconColor = "invert(40%) sepia(6%) saturate(197%) hue-rotate(202deg) brightness(90%) contrast(82%)";
      break;
    case "gray2":
      iconColor = "invert(80%) sepia(1%) saturate(0%) hue-rotate(69deg) brightness(91%) contrast(92%)";
      break;
    case "sub1":
      iconColor = "invert(96%) sepia(5%) saturate(1338%) hue-rotate(82deg) brightness(88%) contrast(103%)";
      break;
    case "sub2":
      iconColor = "invert(94%) sepia(11%) saturate(556%) hue-rotate(33deg) brightness(100%) contrast(91%)";
      break;
    case "white":
      iconColor = "invert(100%) sepia(0%) saturate(7500%) hue-rotate(142deg) brightness(108%) contrast(100%)";
      break;
  }

  return `filter: ${iconColor};`;
}
  • 내가 사용하고 있고, 사용할 color를 정리해서 filter 값을 return 받는 함수를 구현했다.
    CSS filter generator 사이트에 접속해 filter 값을 받았고, 함수에 작성했다.

사용 예시

<RouteBookmarkButton onClick={() => handleBookmarkClick(bookmark)}>
  <img src={`/images/Icon/bookmark_${bookmark}.svg`} alt={`bookmark_${bookmark}`} />
</RouteBookmarkButton>


const RouteBookmarkButton = styled.button`
  ${applyIconColors("gray1")}
  img {
    width: 100%;
    height: 100%;
  }
  width: 30px;
  height: 30px;
  border: none;
  background-color: inherit;
  cursor: pointer;
`;
  • 이렇게 적용하면, 내가 미리 지정해둔 색상을 SVG 파일에 적용할 수 있다.

단점

  • 벨로그를 작성하며, 코드를 다시 읽어보는데 이 방법에는 매우 큰 단점이 있다.
  • 바로, 원하는 색상의 filter 값을 전부 하나하나 작성해야 한다는 것.
    사실 이 프로젝트에서는 아이콘에 사용하는 색상이 한정되어 있었기 때문에 몇 개의 색상 (+ 사용될 수도 있는 색상)을 함수에 넣어줬다.
  • 그런데 이보다 더 다양한 색상으로 바꿔야 한다면? : 이 방법이 효율적이지 않다.

3. 고민해 볼 것

  • 위의 방법이 모든 색상 파일을 관리하는 것보다는 효율적이라고 생각한다.
    하지만, 이전에 생각했던 <g> 태그에 직접 CSS로 넣는 방법이 더 효율적일 수도 있겠다는 생각을 했다.

  • 지금까지는 SVG 파일을 전부 <img> 태그로 가져왔다. 이랬을 경우에, CSS로 fill 속성이나 stroke 속성을 변경하는 것이 불가능하다.
    그렇기 때문에, 이후 리팩토링 과정에서 SVG 파일을 직접 import 해오는 방법을 시도해봐야겠다.

2024.12.08 업데이트

  • svgr을 활용해 svg 파일을 컴포넌트 형태로 import / export 한다.
  • 그리고 사용하는 공간에서 import해서 사용하면, 아이콘이 들어오는 것을 확인할 수 있다.
  • 색상을 변경할 때, styled-components로 스타일링을 해줬다.
const StyledIc = styled(IcRefresh)`
  path {
    fill: ${theme.color.primary};
  }
`
  • fill 속성을 변경하고, 확인해 보면 색상이 변경되어 있다!
    이 방법을 사용하면, 색상이 변경되었다고 해도 한 파일(theme 파일)만 관리하면 되기 때문에 간편하다!!!
    우측 refresh 아이콘 : svgr로 import한 화면!


참고 사이트

0개의 댓글