SVG를 data URI로 바꾸는 방법
- 텍스트 상자에 SVG 마크업을 붙여넣으세요.
.svg파일은 아무 텍스트 편집기로 열어 복사할 수 있습니다. 상자에는 처음에 예시 아이콘이 들어 있습니다. - MIME 유형은 이미
image/svg+xml이고 인코딩은 최적화된 SVG로 설정되어 있습니다. - 옵션 아래의 표를 보세요. Base64, URL 인코딩, 최적화된 SVG 각각의 URI 길이와 gzip 크기가 나오고, 가장 작은 것이 표시되며, 각 행에 사용 버튼이 있습니다.
- 출력 형식을 고르세요. 원본 Data URI, CSS
url(), HTML<img>, HTML<a>, Markdown 중 하나입니다. 그다음 출력 복사를 누르세요.
파일에서 모드로 .svg를 놓을 수도 있습니다. 이 모드는 파일을 그대로 Base64나 URL 인코딩합니다. 최적화 변형과 비교 표는 텍스트 상자에 마크업이 있어야 나옵니다.
Base64와 URL 인코딩 SVG의 크기 비교
둥근 사각형, 원, 선으로 이루어진 309바이트짜리 내장 예시 아이콘에 대해 표는 다음과 같이 보여 줍니다.
| 인코딩 | URI 길이 | Gzip 압축 시 |
|---|---|---|
| Base64 | 438 | 337 |
| URL 인코딩 | 492 | 239 |
| 최적화된 SVG | 347 | 220 |
일반 URL 인코딩은 원본 길이로는 가장 깁니다. 공백, 따옴표, <, >, 줄 바꿈이 모두 세 글자가 되기 때문입니다. 하지만 gzip 뒤에는 Base64를 크게 앞섭니다. 마크업은 반복적인 구조를 유지하지만 Base64는 그것을 뒤섞기 때문입니다. 스타일시트는 거의 항상 압축되어 제공되므로, 실제로 사용자에게 도달하는 것은 gzip 열의 크기입니다.
최적화된 SVG는 두 열 모두에서 가장 작습니다. 103바이트짜리 작은 삼각형 아이콘에서도 차이는 같습니다. Base64 166자, URL 인코딩 172자, 최적화 136자입니다. 아이콘 묶음 전체에 대한 비교는 SVG를 Base64로에 있습니다.
“최적화된 SVG"가 하는 일
최적화는 마크업에 네 가지 변경을 합니다.
- 줄 바꿈을 포함한 연속된 공백을 모두 공백 하나로 줄이고 양 끝을 다듬습니다.
- SVG에
'가 하나도 없을 때만"를'로 바꿉니다. encodeURIComponent로 퍼센트 인코딩한 뒤, URI에서 안전한 문자인 공백,=,:,/,,,;를 되돌립니다.- 남은 이스케이프를 소문자(
%3C대신%3c)로 씁니다. gzip이 조금 더 잘 됩니다. 예시에서는 222바이트 대신 220바이트입니다.
삼각형 아이콘의 결과는 다음과 같습니다.
data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath d='M8 1 15 15H1z' fill='%23e33'/%3e%3c/svg%3e
색상의 #는 %23이 되었습니다. 이 이스케이프는 필수입니다. 이스케이프하지 않은 #는 URL 프래그먼트를 시작하고, 그 뒤의 내용은 아무 경고 없이 버려집니다.
따옴표와 문맥 규칙
최적화 출력에는 작은따옴표, 공백, 괄호가 그대로 들어 있습니다. 큰따옴표 안에서는 괜찮지만 그 밖의 곳에서는 안 됩니다.
.icon { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' ...%3e"); }
<img src="data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' ...%3e" alt="">
따옴표 없는 url(...)은 공백에서 깨지고, 작은따옴표로 감싼 속성은 첫 '에서 끝납니다. URI를 JavaScript로 조립하거나, 템플릿 엔진이 삽입하거나, 따옴표를 바꾸는 시스템에 붙여넣는다면 Base64가 더 안전합니다. 영문자, 숫자, +, /, =만 들어 있어 어떤 문맥에서도 살아남습니다. 표의 사용 버튼으로 전환하세요.
다른 제한은 사소합니다. 최적화된 SVG는 항상 UTF-8이며, 다른 문자 인코딩을 골라도 경고와 함께 무시합니다. 공백 축소는 공백을 보존하는 <text> 요소의 텍스트를 바꿀 수 있습니다. 그리고 이미지로 쓰는 모든 SVG가 그렇듯 루트 요소에 xmlns="http://www.w3.org/2000/svg"가 있어야 합니다.
JavaScript로 구현한 최적화
빌드 스크립트나 CSS-in-JS용으로 같은 변환을 몇 줄에 담을 수 있습니다.
function svgToDataUri(svg) {
let s = svg.trim().replace(/\s+/g, " ");
if (!s.includes("'")) s = s.replaceAll('"', "'");
const keep = { "%20": " ", "%3D": "=", "%3A": ":", "%2F": "/", "%2C": ",", "%3B": ";" };
return "data:image/svg+xml," + encodeURIComponent(s)
.replace(/%[0-9A-F]{2}/g, m => keep[m] || m.toLowerCase());
}
이 함수는 위의 삼각형 URI를 그대로 만듭니다. 브라우저와 Node에서의 인코딩은 JavaScript에서 Base64에서 더 다룹니다. 기존 SVG data URI를 읽으려면 Base64를 SVG로나 Data URI 파서에 붙여넣으세요.
자주 묻는 질문
SVG를 data URI에 넣는 가장 짧은 방법은 무엇인가요?
대개 최적화된 URL 인코딩입니다. 공백을 줄이고, 큰따옴표를 작은따옴표로 바꾸고, 꼭 필요한 문자만 이스케이프합니다. 예시 아이콘에서는 Base64의 438자에 비해 347자입니다.
URL 인코딩한 SVG가 CSS를 깨뜨리는 이유는 무엇인가요?
대부분 따옴표가 충돌하기 때문입니다. 최적화 출력은 안쪽에 작은따옴표를 쓰므로 큰따옴표로 감싸야 합니다: url("data:image/svg+xml,..."). #f00 같은 색상의 #를 이스케이프하지 않아도 URI가 거기서 끊깁니다. %23으로 써야 합니다.
최적화 인코딩을 하면 SVG 모양이 바뀌나요?
일반 그래픽에서는 바뀌지 않습니다. 공백을 줄이고 따옴표 종류를 바꿀 뿐입니다. xml:space="preserve"나 CSS white-space 규칙이 있는 <text> 안의 텍스트는 여분의 공백을 잃을 수 있습니다.
SVG data URI에 ;charset=utf-8을 넣어야 하나요?
필수는 아닙니다. SVG는 XML이고, XML은 파일이 다른 인코딩을 선언하지 않는 한 UTF-8로 읽히므로 한글이나 악센트가 있는 레이블도 그대로 됩니다. 문자 인코딩은 (없음)으로 시작하며, UTF-8을 고르면 14자가 늘지만 해는 없습니다.