완성도 높은 로고를 업로드하고, 운영체제를 다크 모드로 전환한 다음 사이트를 열었다고 해봅시다. 어두운 탭 바에서 밝은 주황색 브랜드 마크가 빛을 내뿜는 자신을 마주하게 됩니다. 평범한 PNG 파비콘은 시스템 테마를 인식하지 못합니다. 하지만 prefers-color-scheme 미디어 쿼리를 내장한 SVG 파비콘이라면 이 문제를 해결할 수 있습니다.
본 가이드는 단 하나의 기법에 초점을 맞춥니다. CSS 미디어 쿼리를 .svg 파일 안에 직접 임베드해, 파일 하나로도 테마에 따라 색상이 자동으로 바뀌도록 만드는 방법입니다. HTML에서 <link> 태그 두 개를 교체하는 방식과는 다른 경로이며, 대부분의 사이트에서 가장 깔끔한 방식입니다.
사전 준비
시작하기 전에 다음 세 가지가 필요합니다.
- 깔끔한
viewBox속성이 정의된 SVG 로고(확장 가능하도록). - SVG 마크업 원본을 직접 편집할 수 있는 기본 지식.
- 사이트
<head>에 link 태그를 추가할 수 있는 권한.
아직 SVG가 없다면 디자인 툴에서 내보내거나, Mzu favicondl을 사용해 어떤 이미지에서든 깔끔한 벡터를 추출할 수 있습니다.
단계별 가이드: SVG 파비콘 안에 미디어 쿼리 추가하기
1단계: 텍스트 에디터에서 SVG 파일 열기
SVG는 그 자체로 XML입니다. .svg 파일을 우클릭한 뒤 연결 프로그램 → TextEdit 또는 VS Code를 선택하세요. 다음과 같은 내용을 확인할 수 있습니다.
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'>
<rect width='64' height='64' rx='12' fill='#ff7a00'/>
<path d='M20 22 L32 44 L44 22' stroke='#fff' stroke-width='6' fill='none'/>
</svg>
2단계: 미디어 쿼리가 포함된 <style> 블록 추가하기
열린 <svg> 태그 바로 아래에 <style> 요소를 삽입합니다. 그 안에서 라이트 테마용 색상을 정의하고, prefers-color-scheme: dark를 사용해 다크 모드용 색상으로 덮어씁니다.
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'>
<style>
.bg { fill: #ff7a00; }
.stroke { stroke: #ffffff; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.stroke { stroke: #ffb347; }
}
</style>
<rect class='bg' width='64' height='64' rx='12'/>
<path class='stroke' d='M20 22 L32 44 L44 22' stroke-width='6' fill='none'/>
</svg>
브라우저는 운영체제 테마가 바뀔 때마다 prefers-color-scheme를 다시 평가합니다. 대부분의 최신 브라우저에서는 새로 고침 없이도 파비콘이 즉시 갱신됩니다.
3단계: HTML <head>에 링크 추가하기
WHATWG HTML Living Standard에 따르면, rel='icon' 링크 타입은 type='image/svg+xml'로 올바른 MIME 타입을 선언하면 SVG를 지원합니다.
<link rel='icon' href='/favicon.svg' type='image/svg+xml'>
이 태그는 PNG 또는 ICO 폴백 링크보다 위에 둡니다. Apple Touch 및 web manifest 항목까지 포함한 전체 모던 스택은 favicon HTML 치트시트에서 확인할 수 있습니다.
4단계: 래스터 폴백 제공하기
모든 브라우저가 파비콘 내부의 CSS를 파싱하지는 않습니다. 특히 구버전 Safari와 일부 임베디드 웹뷰가 그렇습니다. 이런 환경을 위해 32×32 PNG(혹은 멀티 사이즈 ICO)를 함께 제공합니다.
<link rel='icon' href='/favicon.svg' type='image/svg+xml'>
<link rel='icon' href='/favicon.ico' sizes='32x32'>
브라우저는 첫 번째로 일치하는 항목을 사용하므로, SVG가 지원되는 환경에서는 SVG가 우선 적용됩니다.
5단계: 두 가지 컬러 스킴 모두에서 테스트하기
강제 새로 고침(Ctrl/Cmd + Shift + R)을 수행한 뒤 운영체제 테마를 전환합니다. Chrome, Edge, Firefox에서는 탭 아이콘이 실시간으로 바뀌어야 합니다. 변화가 없다면 아래 함정 항목을 참고하세요.
자주 겪는 함정들
함정 1: viewBox를 빠뜨리는 경우
viewBox가 없으면 SVG는 본질적인 크기 그대로 렌더링되며, 너무 크거나 0이 될 수 있습니다. 반드시 viewBox='0 0 64 64'처럼 선언하세요.
함정 2: 인라인 fill 속성이 CSS를 덮어쓰는 경우
도형에 이미 fill='#ff7a00' 같은 속성이 들어가 있다면, CSS 클래스는 우선순위 경합에서 밀립니다. 색상을 클래스로 옮기거나 인라인 속성을 완전히 삭제하세요.
함정 3: 지나치게 강한 파비콘 캐싱
브라우저는 파비콘을 거의 모든 파일보다 강하게 캐싱합니다. SVG를 수정한 뒤에는 테스트 단계에서 쿼리 스트링을 붙여 강제로 다시 불러오게 만드세요. 예: /favicon.svg?v=2. 운영 환경 전략은 캐시 무효화 가이드에서 다룹니다.
함정 4: Safari 핀 탭은 미디어 쿼리를 무시한다
Safari의 핀 탭 기능은 별도의 단색 safari-pinned-tab.svg 파일을 사용합니다. 이 파일 안에 미디어 쿼리를 넣어도 효과가 없습니다. 단색 실루엣으로 디자인하고 <style> 블록은 생략하세요.
함정 5: 다크 모드는 '색상 반전'이 아니다
브라우저의 실제 탭 배경(Chrome의 경우 보통 #2b2a33, Safari는 거의 검은색) 위에서 충분한 대비를 갖는 다크 모드 팔레트를 선택하세요. 아이콘을 한 번 대비 검사 도구에 통과시켜 두면 이후 지원 요청을 줄일 수 있습니다.
마무리
SVG 미디어 쿼리 접근법은 단일 출처 원칙을 제공합니다. 단일 파일, 두 가지 테마, JavaScript는 제로. 이미 SVG 로고를 갖고 있는 모든 모던 사이트의 기본값으로 적합하며, 구버전 브라우저용으로 함께 제공해야 할 PNG와 ICO 폴백을 대체하는 것이 아니라 보완하는 방식으로 작동합니다.
문서화된 사양 확인하기
HTML Standard는 현재 페이지를 대표하는 아이콘의 link 관계로 rel='icon'을 정의합니다.