Иконочный шрифт, SVG-спрайт или inline SVG: что выбрать для сайта
Для большинства сайтов лучший выбор — SVG: спрайт из элементов <symbol>, если иконок много и они повторяются на разных страницах, или inline SVG, если их немного или нужны анимация и несколько цветов. Иконочный шрифт уступает обоим вариантам в доступности и чёткости, поэтому сегодня его оставляют в основном в старых проектах. Ниже — как работает каждый способ и где у него слабые места.
Как работают три способа
Иконочный шрифт
Каждая иконка — символ шрифта, обычно из области Юникода для частного использования (Private Use Area). Шрифт подключают через @font-face, а иконку выводят псевдоэлементом:
@font-face {
font-family: "icons";
src: url("/fonts/icons.woff2") format("woff2");
font-display: block;
}
.icon-cart::before { font-family: "icons"; content: "\e001"; }
Цвет и размер задаются как у текста — свойствами color и font-size. Собрать такой шрифт из своих SVG можно генератором иконочного шрифта: на выходе получится woff2 и готовый CSS.
SVG-спрайт
Все иконки лежат в одном файле, каждая — внутри <symbol> со своим id. На странице иконку подключают ссылкой через <use>:
<svg class="icon" width="24" height="24" aria-hidden="true">
<use href="/sprite.svg#cart"></use>
</svg>
Файл спрайта кэшируется браузером, а currentColor внутри символов берёт цвет у <svg> на странице. Внешний спрайт должен лежать на том же домене, что и сайт: загрузку для <use> с чужого домена браузеры блокируют даже при настроенном CORS. Собрать спрайт из набора файлов поможет генератор SVG-спрайтов.
Inline SVG
Код иконки вставляется прямо в HTML. Дополнительных запросов нет, и каждый элемент доступен для CSS: можно анимировать отдельные линии и красить части в разные цвета. Минус — код повторяется при каждом использовании и не кэшируется отдельно от страницы. В компонентных фреймворках это почти незаметно: иконка живёт в компоненте, а сжатие gzip или Brotli хорошо справляется с повторами. На страницах векторных иконок freeicons есть кнопка «Копировать как React».
Доступность
Здесь у шрифтов главная проблема. Скринридер может попытаться прочитать символ из области частного использования или сгенерированный CSS-контент, и пользователь услышит бессмыслицу или ничего. Если шрифт не загрузился или посетитель запретил сайтам менять шрифты — такая настройка есть, например, в Firefox, — вместо иконок появятся пустые квадраты или случайные символы.
С SVG правила проще:
- декоративная иконка рядом с текстом —
aria-hidden="true", действие объяснит сам текст; - кнопка только с иконкой — подпись на самой кнопке:
<button aria-label="Удалить">; - самостоятельная смысловая картинка —
role="img"иaria-labelу<svg>.
Со шрифтом можно добиться того же: aria-hidden на иконке и визуально скрытый текст рядом. Но об этом чаще забывают, а ошибку не видно глазами.
Скорость загрузки
- Шрифт — один файл, который загружается целиком, даже если на странице две иконки из двухсот. Пока он грузится, иконок нет:
font-display: blockна это время прячет символы, иначе на их месте мелькнут квадраты или буквы запасного шрифта. - Спрайт — тоже один кэшируемый файл. Собирайте его под проект, без неиспользуемых символов.
- Inline SVG появляется сразу вместе с HTML, но увеличивает размер страницы: для десятка иконок это оправдано, для сотен повторов в каталоге — уже нет.
Для всех SVG-вариантов оптимизируйте исходники через SVGO: удаление метаданных и лишней точности координат уменьшает и спрайт, и HTML.
Качество отрисовки
Шрифт рисуется как текст: к нему применяются сглаживание и хинтинг, а положение зависит от line-height и метрик шрифта. Отсюда размытые края, иконки, смещённые на пиксель относительно текста, и разная толщина линий в разных браузерах и системах. SVG рисуется как геометрия: иконка, построенная на сетке 24×24, в 24 px выглядит так, как задумал дизайнер.
Ещё одно ограничение — цвет. Символ шрифта окрашивается целиком в один цвет, а SVG может сочетать несколько: основной через currentColor и дополнительные через CSS-переменные. Подробнее — в статье о способах изменить цвет SVG.
Сравнение
| Критерий | Иконочный шрифт | SVG-спрайт | Inline SVG |
|---|---|---|---|
| Доступность | нужны обходные приёмы | хорошая | хорошая |
| Чёткость | как у текста, возможна размытость | высокая | высокая |
| Цвет | один, через color | currentColor и переменные | любой, вплоть до отдельных частей |
| Кэширование | да | да, если файл внешний | нет, в составе HTML |
| Когда видна иконка | после загрузки шрифта | после загрузки спрайта | сразу с HTML |
| Анимация частей | нет | ограничена | полная |
Что выбрать
- Сайт с десятками иконок на многих страницах — внешний SVG-спрайт.
- Приложение на React, Vue или Svelte — inline SVG в компонентах.
- Лендинг с несколькими иконками — inline SVG прямо в разметке.
- Старый проект на иконочном шрифте — переписывать всё сразу не обязательно: добавьте
aria-hiddenи текстовые подписи, а новые иконки подключайте через SVG.
Для старта удобно взять иконки интерфейса в линейном стиле: они построены на сетке 24×24 и окрашиваются через currentColor.
Итог
Иконочные шрифты решали задачи тех лет, когда SVG поддерживался плохо. Сегодня спрайт и inline SVG дают лучшую доступность, чёткость и контроль над цветом при сопоставимой скорости, а шрифт разумно оставить только для поддержки старого кода.