
아이콘 몇 개 넣겠다고 Font Awesome 전체를 불러온 적 있으신가요? 저도 한동안 그렇게 했습니다. 어느 날 PageSpeed Insights 점수를 보고서야 뭔가 잘못됐다는 걸 실감했고, 그때부터 아이콘 하나를 어떻게 쓰는지가 생각보다 중요한 문제라는 걸 알게 됐습니다. 아이콘 폰트에서 SVG로, 그리고 AI 생성까지 직접 겪으며 느낀 것들을 풀어봅니다.
아이콘 폰트, 편하긴 한데 뭔가 이상했습니다
Font Awesome이나 Material Icons 같은 아이콘 폰트는 처음엔 정말 편했습니다. 클래스 하나만 붙이면 아이콘이 나오니까요. 그런데 쓰는 아이콘은 다섯 개인데 수백 KB짜리 폰트 파일 전체를 CDN에서 받아오는 구조가 계속 마음에 걸렸습니다.
아이콘 폰트 방식의 핵심 문제는 렌더링 방식에 있습니다. 아이콘 폰트는 텍스트로 취급되기 때문에 안티앨리어싱(anti-aliasing), 즉 화면에서 글자나 이미지의 경계를 부드럽게 처리하는 기술의 영향을 받습니다. 이 때문에 작은 사이즈에서 아이콘이 흐릿하게 보이는 경우가 생기고, 레티나 디스플레이에서도 기대만큼 선명하지 않을 때가 있습니다. 제가 직접 써봤는데, 고해상도 모니터에서 16px짜리 아이콘이 희미하게 보여서 한참 원인을 찾았던 기억이 있습니다.
대안으로 SVG 스프라이트(sprite) 방식도 써봤습니다. SVG 스프라이트란 여러 아이콘을 하나의 SVG 파일에 묶어두고 use 태그로 필요한 것만 꺼내 쓰는 방식입니다. 파일 요청 횟수를 줄일 수 있다는 장점이 있지만, 팀원이 아이콘을 하나 추가할 때마다 스프라이트 파일을 직접 수정해야 해서 협업 환경에서는 생각보다 불편했습니다.
AI로 SVG를 직접 만들어보니
SVG 스프라이트의 번거로움을 느끼던 시점에 Claude를 활용한 아이콘 생성을 시도해봤습니다. "체크박스 아이콘, 스트로크 스타일, strokeWidth 2, 24x24 viewBox"라고 입력하면 바로 사용 가능한 SVG 코드가 나왔습니다. 기존 라이브러리에서 딱 맞는 스타일을 찾지 못해 수십 분을 헤매던 걸 5초 만에 해결하는 경험은 솔직히 예상 밖이었습니다.
SVG는 벡터 그래픽(vector graphics) 포맷입니다. 벡터 그래픽이란 수학적 좌표와 수식으로 이미지를 표현하는 방식으로, AVIF나 WebP처럼 픽셀 단위로 저장하는 비트맵(bitmap) 포맷과 달리 어떤 해상도에서도 깨지지 않습니다. 아이콘과 로고처럼 선명도가 중요한 요소에 SVG가 적합한 이유가 바로 이것입니다.
그런데 AI가 생성한 SVG를 그대로 쓰기엔 문제가 있었습니다. 불필요한 transform 속성, 중복된 g 태그, 닫히지 않은 패스(path) 등이 종종 포함돼 있었습니다. 그래서 SVGO라는 최적화 도구를 후처리 단계로 반드시 거쳤습니다. SVGO란 SVG 파일에서 불필요한 메타데이터, 빈 태그, 중복 속성 등을 자동으로 제거해주는 Node.js 기반 최적화 라이브러리입니다(출처: SVGO GitHub). 이 단계를 빠뜨리면 AI가 만든 SVG가 오히려 수작업 아이콘보다 용량이 클 수도 있으니 주의해야 합니다.
인라인 SVG와 CSS 변수로 다크 모드 대응하기
아이콘을 HTML에 직접 삽입하는 인라인 SVG(inline SVG) 방식은 외부 파일 요청 없이 DOM에서 바로 조작할 수 있다는 점에서 성능 면의 이점이 있습니다. 인라인 SVG란 <img> 태그로 외부 파일을 참조하는 대신, SVG 코드 자체를 HTML 문서 안에 그대로 넣는 방식입니다.
제가 특히 유용하게 쓴 건 fill="currentColor" 속성입니다. 이 속성은 부모 요소의 CSS color 값을 그대로 상속받아 아이콘 색상에 적용합니다. 여기에 CSS 커스텀 프로퍼티(custom property), 즉 --icon-color 같은 CSS 변수를 연결하면 다크 모드 전환 시 아이콘 색상이 이미지 파일 교체 없이 자동으로 바뀝니다. 라이트/다크 모드 대응을 CSS 한 줄로 해결했을 때는 저도 처음엔 이게 된다고? 싶었습니다.
다만 복잡도에 따라 전략을 나눠야 합니다. 핵심 포인트를 정리하면 다음과 같습니다.
- 단순 아이콘(선, 도형 위주): 인라인 SVG로 삽입해 CSS 변수와 연결
- 그라디언트·클리핑 마스크가 포함된 복잡한 SVG:
<img>태그로 외부 참조 - 팀 협업 환경에서 반복 사용되는 아이콘: Lucide, Heroicons 같은 라이브러리 활용
인라인으로 복잡한 SVG를 대거 넣으면 HTML 소스가 지저분해져서 유지보수가 어려워집니다. 제 경험상 이건 "SVG는 무조건 인라인"이 아니라 상황에 따라 섞어 쓰는 게 맞습니다.
AI 생성 SVG의 한계, 특히 접근성 문제
AI가 SVG를 만들어준다는 건 분명한 강점입니다. 그런데 제가 직접 써보면서 가장 신경 쓰인 부분이 있었는데, 바로 접근성(accessibility)이었습니다.
AI가 생성한 SVG는 대부분 aria-label, role="img", <title> 태그 없이 순수 시각 요소로만 구성됩니다. 여기서 aria-label이란 WAI-ARIA(Web Accessibility Initiative – Accessible Rich Internet Applications) 명세의 속성으로, 스크린 리더가 해당 요소를 음성으로 읽을 때 사용할 텍스트를 지정하는 역할을 합니다. 이 속성이 없으면 시각 장애 사용자는 아이콘의 의미를 전혀 알 수 없습니다.
웹 접근성은 선택이 아닌 기준입니다. 국내에서도 장애인차별금지법에 따라 공공기관 및 일정 규모 이상의 민간 사이트는 웹 접근성 준수 의무가 있으며, 한국웹접근성인증평가원은 이를 기반으로 인증 심사를 진행합니다(출처: 한국웹접근성인증평가원). AI에게 SVG를 요청할 때 "aria-label과 role 속성 포함"을 명시하는 습관이 없으면, 나중에 접근성 감사에서 대량 수정이 필요해집니다.
또 한 가지, "SVG를 직접 만든다"는 접근 자체가 유지보수 복잡성을 높인다는 점도 인식해야 합니다. 팀 환경에서는 일관된 디자인 시스템을 유지하는 것이 품질 통제 측면에서 더 유리할 수 있습니다. AI 생성 아이콘은 1인 프로젝트나 빠른 프로토타이핑에 적합하고, 프로덕션 팀 환경에서는 신중하게 적용 범위를 정해야 한다고 봅니다.
SVG 형식의 기술 명세와 활용에 대한 상세한 내용은 MDN Web Docs에서 확인할 수 있습니다(출처: MDN Web Docs).
아이콘 하나가 얼마나 많은 선택지를 요구하는지, 막상 고민해보면 생각보다 깊어집니다. 지금 당장 Font Awesome을 걷어낼 필요는 없지만, 다음 프로젝트를 시작할 때는 인라인 SVG와 AI 생성을 조합하는 방식을 한 번쯤 시도해보시길 권합니다. 다크 모드 대응까지 CSS 한 줄로 해결되는 경험을 하고 나면, 돌아가기가 쉽지 않을 겁니다.
참고:
- MDN Web Docs, "SVG" — https://developer.mozilla.org/ko/docs/Web/SVG
- SVGO GitHub — https://github.com/svg/svgo
- velog, "이미지 로딩성능 최적화" — https://velog.io/@min5x5/이미지영상-로딩성능-최적화