SVG Symbol
Альтернатива шрифтовым иконкам — использование SVG-спрайтов с символами для встраивания масштабируемых многоцветных иконок непосредственно в HTML.
Что такое SVG-спрайты с символами?
SVG-спрайты с символами объединяют несколько SVG-иконок в один файл. Каждая иконка определяется внутри элемента <symbol> с уникальным id. Для использования иконки вы ссылаетесь на неё с помощью <use href="#icon-id">. Спрайт загружается один раз — либо встроенным, либо как внешний файл — и отдельные иконки отображаются в любом месте страницы.
Это принципиально иной подход по сравнению со шрифтовыми иконками. Вместо сопоставления кодовых точек Unicode с глифами шрифта вы используете нативные SVG-элементы. Каждая иконка сохраняет все возможности SVG: несколько цветов, градиенты, фильтры и детализированные атрибуты доступности. Компромис — несколько более сложная разметка и соглашения по стилизации по сравнению с чисто CSS-подходом шрифтовых иконок.
Как это работает
Файл спрайта — это обычный SVG-документ, содержащий один или несколько элементов <symbol>. Каждый символ определяет самодостаточную иконку со своим viewBox:
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-home" viewBox="0 0 24 24">
<path d="M3 12l9-9 9 9M5 10v10a1 1 0 001 1h3a1 1 0 001-1v-4..."/>
</symbol>
<symbol id="icon-search" viewBox="0 0 24 24">
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
</symbol>
</svg>
Внешний элемент <svg> скрыт через style="display:none", чтобы не занимать место на странице. Символы внутри невидимы до их использования. Для отображения иконки используйте элемент <use>:
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>
Стилизуйте иконки через CSS, используя fill и stroke вместо шрифтового свойства color:
.icon {
width: 24px;
height: 24px;
fill: currentColor;
stroke: none;
}
Использование fill: currentColor позволяет иконке наследовать цвет текста родительского элемента, аналогично тому, как шрифтовые иконки работают со свойством color.
Символы vs шрифтовые иконки
- Поддержка нескольких цветов — каждый контур может иметь собственную заливку и обводку
- Каждая иконка — реальный SVG-элемент с лучшей доступностью
- Не нужна сопоставление Unicode — ссылайтесь на иконки по читаемым именам
- Более чёткий рендеринг — никаких проблем с хинтингом или субпиксельных артефактов
- Отдельные части иконки можно анимировать независимо
- Работает с любыми SVG-функциями: градиенты, фильтры, обтравочные контуры, маски
- Более громоздкая разметка (
<svg><use>вместо<i class="icon">) - Сложно стилизовать через CSS
color— нужныfill/stroke - Внешние спрайты имеют последствия CORS при загрузке между источниками
- Общий размер файла больше, чем у сжатых шрифтовых форматов
- Больше HTML-веса при каждом использовании иконки
- Нет поддержки псевдоэлементов
::before/::after
Стратегии загрузки
Существует три основных способа загрузки SVG-спрайта с символами в страницу, каждый с разными компромиссами:
Встроенный спрайт
Вставьте весь спрайтовый SVG непосредственно в тег HTML <body>. Это наиболее простой подход — без проблем CORS, без дополнительного HTTP-запроса. Символы немедленно доступны для любой ссылки <use> на странице. Лучше всего подходит для одностраничных приложений или при небольших наборах иконок (менее ~50).
Внешний спрайт
Загрузите спрайт как внешний файл через <use href="icons.svg#home">. Это сохраняет HTML чистым и позволяет браузеру кэшировать спрайт отдельно от страницы. Однако это имеет последствия для CORS: спрайт должен обслуживаться с того же источника, или сервер должен установить соответствующие заголовки Access-Control-Allow-Origin. Обратите внимание, что Internet Explorer не поддерживает внешние ссылки <use> — используйте полифил svg4everybody, если нужна поддержка IE.
Внедрение через JS
Загрузите файл спрайта через fetch() и внедрите его в DOM во время выполнения. Это сочетает возможность кэширования внешних спрайтов с надёжностью встроенных — внедрённый SVG становится частью документа, поэтому ссылки <use> работают без ограничений CORS. Bobcorn генерирует именно такой подход: JS-файл, который получает и регистрирует все символы при загрузке.
<!-- Загрузка сгенерированного JS-спрайта -->
<script src="icons-symbol.js"></script>
<!-- Затем используйте как обычно: -->
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>
JS-файл создаёт скрытый элемент <svg>, содержащий все определения <symbol>, и добавляет его в тело документа. После загрузки на иконки ссылаются так же, как при встроенном подходе.
Когда использовать SVG-символы
SVG-спрайты с символами — правильный выбор, когда проекту нужны возможности, которые шрифтовые иконки не могут обеспечить:
- Многоцветные иконки — когда иконки используют более одного цвета, градиенты или сложные заливки, которые одноглифный шрифт не может представить
- Доступность — главный приоритет — каждая иконка может включать элемент
<title>и атрибутaria-label, предоставляя скринридерам значимые описания - Анимация частей иконки — когда нужно анимировать отдельные контуры или группы внутри иконки (например, вращающаяся шестерёнка внутри иконки настроек)
- Проекты с интенсивным использованием SVG — приложение уже активно использует встроенный SVG, поэтому символы органично вписываются в существующую архитектуру
- Максимальная чёткость рендеринга — хинтинг шрифтов может вызывать проблемы выравнивания на маленьких размерах; SVG-символы рендерятся попиксельно идеально при любых размерах
Когда оставаться при шрифтовых иконках
Шрифтовые иконки остаются лучшим выбором в нескольких распространённых сценариях:
- Большие наборы иконок (200+) — сжатый WOFF2-шрифт значительно меньше, чем SVG-спрайт с тем же количеством иконок
- Все иконки монохромные — если каждая иконка одноцветная, шрифтовые иконки обеспечивают наиболее простую интеграцию без компромиссов
- Интеграция только через CSS — шрифтовым иконкам нужна лишь ссылка на таблицу стилей и CSS-классы, без JavaScript или дополнительной разметки
- Устаревшие системы — проекты, уже использующие шрифтовые иконки, недостаточно выиграют от перехода, чтобы оправдать усилия по миграции
- Поддержка псевдоэлементов — вам нужны иконки в псевдоэлементах
::beforeили::after, которые работают только с глифами шрифта