- 프로젝트: loplat UI
- 키워드: svg, mask, fill
- 상황
- 팀원분께서 IconButton이라는 컴포넌트를 개발하셨는데, 이상한 점이 있다고 하셨다.
"svg에 border와 동일한 색상을 설정했는데 svg의 색상이 border색상보다 좀더 밝게 나타납니다." - 실제로 확인해보니 border color와 svg fill 에 동일한 색상을 전달하지만, storybook 상에는 색상이 다르게 보이는 것을 확인했다.
border-color: ${({ border }) => border.default}; svg path { fill: ${({ text }) => text.default}; }
- 팀원분께서 IconButton이라는 컴포넌트를 개발하셨는데, 이상한 점이 있다고 하셨다.
- 해결 과정
- 개발자도구로 확인한 결과, svg path에는 정상적으로 fill 속성이 채워져있었다.
fill의 색상이 border와 동일했지만, svg path가 좀 더 연하게 보였다. - element 탭을 눈여겨보던 와중에, 바로위에 <defs> tag가 있는 것을 발견했다.
defs 아래에도 path가 있었는데, css 선택자가 'svg path'였기 때문에 defs에 있는 path에도 fill 속성이 들어가있었다. - 다시 svg 구조를 살펴보니 mask를 이용하여 svg icon을 그리고 있었다.
Icon에 해당하는 path는 mask 아래 use를 통해 들어가있었고, '<path d="M-2-2h32v32H-2z"></path>' 라는 정사각형 path와 mask 를 조합해서 Icon을 그리고 있는 것이었다.<g transform="translate(2 2)" fill="none" fill-rule="evenodd"> <mask id="campaign_svg__b__0mpvmuvoi" fill="#fff"> <use xlink:href="#campaign_svg__a__0mpvmuvoi"></use> // defs 아래에 있던 path </mask> <g mask="url(#campaign_svg__b__0mpvmuvoi)"> <path d="M-2-2h32v32H-2z"></path> </g> </g>
- svg mask(https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mask)는 fill="white"일 때 mask가 덮고 있는 영역이 모두 보이고, fill="black" 일때는 mask가 덮고 있는 영역이 보이지 않게 된다.
즉, 정사각형(d="M-2-2h32v32H-2z") 영역 중에서, Icon에 해당하는 path만 보이고 나머지는 보이지 않도록 mask가 작동해야한다.
정사각형의 색상이 원래 원하던 색상이므로, Icon에 해당하는 path(즉, mask안에 있는 campaign_svg__a path) 의 fill 값은 'white'여야한다.
하지만 현재는 모든 path의 색상이 빨간색(white와 black의 중간)이므로 원하던 색상보다 조금 연하게 보였던 것이다.(완전히 보이지도(white) 숨겨지지도(black) 않은 중간 상태) - defs 아래에 있는 (mask용) path는 제외하고 g 태그 아래에 있는 path에만 원하는 색상을 적용하도록 수정했다.
svg g > path { fill: ${({ text }) => text.default}; }
- 이제 원하는대로 마스킹이 일어난다!
- 개발자도구로 확인한 결과, svg path에는 정상적으로 fill 속성이 채워져있었다.
'프론트엔드' 카테고리의 다른 글
Firebase storage로 첨부파일 다운로드 구현하기 (0) | 2021.12.06 |
---|---|
absolute와 fixed로 다양한 스마트폰 너비 대응하기 (0) | 2021.12.05 |
번들링 최적화를 통해 import cost 줄이기(2) (0) | 2021.11.28 |
번들링 최적화를 통해 import cost 줄이기(1) (0) | 2021.11.25 |
Chrome과 안드로이드 기기를 유선/무선 연결하기 (0) | 2021.11.23 |