Как превратить SVG в data URI
- Вставьте разметку SVG в поле Текст. Чтобы её скопировать, откройте файл
.svgв любом текстовом редакторе. Изначально в поле стоит иконка-пример. - MIME-тип уже
image/svg+xml, а Кодирование установлено на Оптимизированный SVG. - Посмотрите таблицу под настройками. В ней указаны длина URI и размер после gzip для Base64, URL-кодирования и оптимизированного SVG, отмечен самый короткий вариант, и у каждого есть кнопка Выбрать.
- Выберите Формат вывода: чистый Data URI, CSS
url(), HTML<img>, HTML<a>или Markdown. Затем нажмите Скопировать результат.
В режиме Из файла можно перетащить .svg – тогда доступны Base64 и URL-кодирование файла как есть. Для оптимизированного варианта и таблицы сравнения нужна разметка в текстовом поле.
Три кодирования в реальных цифрах
Для встроенного примера (иконка на 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: пробел,=,:,/,,и;. - Записывает оставшиеся escape-последовательности строчными буквами (
%3cвместо%3C): так gzip сжимает чуть лучше, 220 байт вместо 222 для примера.
Результат для иконки-треугольника:
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>, которые сохраняют пробелы. И корневому элементу всё равно нужен xmlns="http://www.w3.org/2000/svg", как любому 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 описано в статье Base64 в JavaScript. Чтобы прочитать готовый data URI с SVG, вставьте его в Base64 в SVG или в парсер Data URI.
Вопросы и ответы
Как короче всего вставить SVG в data URI?
Обычно это оптимизированное URL-кодирование: пробелы схлопнуты, двойные кавычки заменены одинарными, экранируются только нужные символы. Для иконки-примера это 347 символов против 438 у Base64.
Почему URL-кодированный SVG ломает CSS?
Чаще всего конфликтуют кавычки. Оптимизированный вариант использует внутри одинарные кавычки, поэтому снаружи должны быть двойные: url("data:image/svg+xml,..."). Неэкранированный # в цвете вроде #f00 тоже обрывает URI, поэтому его нужно записать как %23.
Меняет ли оптимизированное кодирование внешний вид SVG?
Для обычной графики нет. Оно лишь схлопывает пробелы и меняет стиль кавычек. Текст внутри <text> с xml:space="preserve" или CSS-правилом white-space может потерять лишние пробелы.
Нужно ли добавлять ;charset=utf-8 в data URI с SVG?
Не обязательно. SVG – это XML, а XML читается как UTF-8, если в файле не объявлена другая кодировка, так что подписи с диакритикой работают и без этого. Кодировка по умолчанию стоит на (нет); выбор UTF-8 добавляет 14 символов и ничему не вредит.