SVG Symbol

Альтернатива шрифтовым иконкам — использование SVG-спрайтов с символами для встраивания масштабируемых многоцветных иконок непосредственно в HTML.

Что такое SVG-спрайты с символами?

SVG-спрайты с символами объединяют несколько SVG-иконок в один файл. Каждая иконка определяется внутри элемента <symbol> с уникальным id. Для использования иконки вы ссылаетесь на неё с помощью <use href="#icon-id">. Спрайт загружается один раз — либо встроенным, либо как внешний файл — и отдельные иконки отображаются в любом месте страницы.

Это принципиально иной подход по сравнению со шрифтовыми иконками. Вместо сопоставления кодовых точек Unicode с глифами шрифта вы используете нативные SVG-элементы. Каждая иконка сохраняет все возможности SVG: несколько цветов, градиенты, фильтры и детализированные атрибуты доступности. Компромис — несколько более сложная разметка и соглашения по стилизации по сравнению с чисто CSS-подходом шрифтовых иконок.

Как это работает

Файл спрайта — это обычный SVG-документ, содержащий один или несколько элементов <symbol>. Каждый символ определяет самодостаточную иконку со своим viewBox:

icons.svg (файл спрайта)
<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>:

Использование символов в HTML
<svg class="icon"><use href="#icon-home"></use></svg>
<svg class="icon"><use href="#icon-search"></use></svg>

Стилизуйте иконки через CSS, используя fill и stroke вместо шрифтового свойства color:

CSS для SVG-иконок
.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 (вывод Bobcorn)
<!-- Загрузка сгенерированного 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, которые работают только с глифами шрифта
В Bobcorn
Bobcorn может экспортировать ваши иконки в виде JS-спрайта с символами наряду с шрифтовыми файлами. Включите опцию JS в диалоге экспорта. Сгенерированный файл создаёт встроенный SVG-спрайт и регистрирует все символы при загрузке. В одном проекте можно использовать оба подхода — шрифты для простых UI-иконок, символы для сложных цветных иллюстраций.
Совет
Не обязательно выбирать что-то одно. Многие дизайн-системы используют шрифтовые иконки для большинства монохромных UI-иконок (кнопки, навигация, элементы форм) и SVG-символы для нескольких многоцветных иллюстраций или анимированных иконок. Диалог экспорта Bobcorn позволяет генерировать оба варианта в одном экспорте.