Icon Font란 무엇일까?
디자이너 없이 FE 개발자가 웹 사이트를 개발할 때 아이콘이 필요하면 보통 FontAwesome 패키지 등에서 제공하는 아이콘을 이용한다. 그렇다면 디자이너가 Figma에 그려준 아이콘은 어떻게 사용할까? 본인은 svg를 export하여 사용했는데 이 과정에서 사이즈나 컬러 설정과 관련한 까다로운 선택과 설정들을 겪었고, 또 Icon Font의 선택지도 존재함을 뒤늦게 알게되어 공유 차원에서 글을 작성하게 되었다.
Icon Font란?
디지털 폰트는 문자, 특수 문자, 숫자 등에 unicode라는 문자열을 할당하여 사용된다. 예를들면 "A" 문자는 "U+0041"이라는 unicode가 할당된다. 마찬가지로 Icon Font도 Font이다. 그렇기 때문에 별도의 unicode가 존재하고 이 unicode를 이용하여 Icon을 보여주게된다.
Icon Font와 svg 비교
Icon Font는 vector-based이고, svg도 vector-based이다. 그렇다면 svg를 Icon Font 로 사용해도 되지 않을까 싶은데 다음과 같이 몇 가지 차이점이 존재한다.
1. flexibility 관점
svg가 디자인에 있어서 flexibility가 높다. Icon Font는 아래 이미지에 보이듯 단면만 렌더링 가능하고 단일 컬러만 허용하지만, svg는 여러 면을 렌더링 가능하고 더 많은 컬러 적용이 가능하다. 심지어는 애니메이션 적용까지 가능하다. 이는 svg와 js로만든 눈을 깜빡이는 고양이 예제를 보면 알 수 있다.
2. Positioning 관점
Icon Font는 말 그대로 Font다. 그래서 위치 설정은 글꼴 규칙에 영향을 받기 때문에 까다로울 수 있다. (그래서 자체적으로 만들기보단 Icon Font 프로바이더에서 제공하는 Icon Font를 사용한다.)
3. Accessibility 관점
svg는 <title>
, <desc>
, alt 속성 등을 통해서 접근성을 제공할 수 있고, Icon Font는 aria를 사용해야 한다.
4. Styling 관점
Icon Font는 일반적인 컬러나 사이즈 수정이 흔히 아는 css의 color와 fontSize를 이용하기 때문에 매우 쉽지만, svg는 조금 까다롭다. 이 부분은 바로 다음 목차에서 알아보자.
svg 이미지의 컬러와 사이즈 수정
nextjs에서 svg 이미지를 사용할 때 컬러와 사이즈를 수정하기 위한 여러 선택지가 존재한다.
1. 파일 수정 vs prop 전달
컬러와 사이즈를 수정하기 위한 방법으로는 파일 내의 width, height, fill, viewBox를 직접 수정하거나, prop으로 width, height, color를 넘기는 방법 두 가지가 존재하는데, 전자는 아무래도 파일에 접근해서 직접 수정해야 하다보니 후자를 선택하게된다.
2. <img >
와 svgr package 비교
prop으로 전달하기 위한 방법으로는 img 태그를 이용하거나 svg를 react 컴포넌트로 바꿔주는 svgr 패키지가 필요하다.
img 태그를 이용하는 경우 <img src="/image.svg" alt="" />
와 같이 작성하게 돼서 alt도 이용이 가능하다. 하지만 이 경우 두 가지 문제점이 존재한다.
첫 번째는 color를 변경하기 위해서는 filter css를 이용해야한다.
보통 color를 표현할 때 hex code를 쓰는데 이는 적용되지 않기 때문에 filter css를 이용해야 한다. 그런데 filter는 hex code에 비해서 표현이 장황하다. 예를들면 #fff
를 filter로 표기하면 invert(100%) sepia(2%) saturate(0%) hue-rotate(213deg) brightness(103%) contrast(100%)
가 된다. 물론 hex code를 filter css로 변경해주는 방법도 존재하지만, 역시 번거롭다.
두 번째는 svg에 대한 직접적인 제어가 불가능해진다. 앞에서 설명했던 눈을 깜빡이는 고양이 예제처럼 스크립트로의 제어가 불가하다.
이러한 문제를 피하고자 svgr을 선택하게되면 두 가지 불편함이 따라온다.
첫 번째는 import ComponentName from ~
형태로만 이미지를 가져올 수 있다. 그렇기 때문에 다음과 같은 코드를 작성하기가 쉽지 않다.
const IconButtonGroup = ({ icons }) => { return ( <ul> {icons.map(icon => { return ( <li>{icon}</li> // 🤔 svgr을 이용해서 어떻게 Icon을 보여줄 것인가? ); })} </ul> ); };
물론, dynamic import를 사용하면 어찌저찌 우회해서 구현이 가능하겠지만, img 태그를 이용하는 경우에 비해 코드량이 훨씬 많아진다.
두 번째는 별도의 웹펙 및 타입스크립트 지원 설정이 필요하다는 점이다.
Icon Font를 사용하게 되면 위와 같은 복잡한 과정을 밟지 않고 다음과 같이 사이즈, 컬러 설정이 가능하다.
<span className="font-icon dog" style={{ color: "red", fontSize: "36px" }} />
Icon Font와 Image File 비교
Icon Font는 Font기 때문에 .TTF, .OTF와 같은 폰트 포맷 형식을 갖게 되는데 이러한 형식들은 raster-based 이미지의 형식인 .JPG, .PNG 파일들에 비해서 파일 용량이 훨씬 더 작다. 그리고 이는 페이지의 로딩 속도 단축으로 이어진다.
더불어서 Icon Font를 사용하기 위해 필요한 것은 한 개의 폰트 파일 뿐이어서, 웹 페이지를 로드해올 때 서버에 이미지 요청과 관련한 HTTP 요청 수를 줄일 수 있다. 반면에 이미지 파일을 이용하는 경우에는 이미지 파일 마다 개별적인 HTTP 요청이 발생해야 한다.
그렇다면 Icon Font가 웹 사이트의 모든 이미지 파일들을 대체할 수 있을까? 앞서 설명했듯, Icon Font는 단일 컬러를 가진 평면물만 렌더링이 가능하다는 한계점이 존재한다.
Icon Font는 어떻게 사용할까?
Icon Font를 이용할 때는 보통 <i>
태그와 함께 다음과 같은 형태로 사용이 가능하다.
<p><i class="font-icon dog"></i></p>
이를 위해서는 몇 가지 설정이 필요한데, 먼저 다음과 같이 @font-face
를 통해서 원하는 아이콘이 포함된 폰트 파일을 로드해온다.
@font-face { font-family: myIconFont; src: url(https://example.com/fonts/myiconfont.woff); }
그리고 로드해올 font-family, 그러니까 로드해올 Icon Font를 사용할 클래스 명을 정한다. 여기서는 "font-icon"로 하겠다. 또한 아이콘을 보여줄 때는 보통 ::before
나 ::after
와 같은 pseudo-element를 이용해서 보여주기 때문에 이를 반영하여 작성한다.
.font-icon::before { font-family: myIconFont; }
앞서 작성한 HTML에서는 dog 아이콘에 접근하고 있다. 이를 위해서는 다음과 같이 스타일을 작성하여 아이콘을 보여줄 수 있다.
.font-icon.dog::before { content: "041" }
여기서 041은 dog 아이콘의 unicode이다.
참고로 svg를 Icon Font로 변환해주는 사이트는 icomoon이나 Fontello 등을 포함하여 여러 사이트가 존재하고, Figma 플러그인 중에도 Icon Font Generator가 존재하므로 필요에 따라서 변환하여 사용하자.
참고 문헌
What Is an Icon Font? (And How to Use One) | Design Shack
How and Why Icon Fonts Are Used On the Web - tekRESCUE
Creating and Implementing Your Own Icon Font – A Tutorial - The Media Temple Blog