Иконки — это мелочь, которая не мелочь. Неправильный выбор метода замедляет страницу, ломает доступность для людей со скринридерами и делает поддержку мучительной через полгода. Три основных подхода сейчас: иконочные шрифты, SVG прямо в HTML и SVG-спрайты. Каждый из них решает задачу по-своему.
Иконочные шрифты — Font Awesome и иже с ним
Ещё в 2013–2015 годах это был стандарт. Font Awesome, Material Icons, Feather, Ionicons — подключил один файл шрифта, расставил классы в HTML, иконки появились. Удобно.
Механика простая: каждая иконка — это символ в юникоде, которому шрифт сопоставляет глиф-рисунок. Браузер рендерит её как обычный текст.
Плюсы реальные: масштабируется без потери качества, цвет меняется через color в CSS, подключение за пять минут.
Но минусы серьёзнее.
Размер. Полный Font Awesome 6 — это около 400 КБ только в шрифтовых файлах (woff2). Даже если ты используешь 8 иконок из 2000 в библиотеке. Браузер всё равно грузит весь файл.
FOIT — мигание невидимого текста. Браузер парсит HTML, грузит CSS, потом шрифт — и только потом показывает иконки. Пока шрифт не пришёл, на экране либо пусто, либо квадратики с кодом юникода. На медленном соединении это заметно.
Доступность. Скринридеры читают символы иконочного шрифта как непонятные знаки или вообще пропускают их. Нужно вручную добавлять aria-hidden="true" везде, и о большинстве мест разработчики забывают.
Цвет — только один. Сделать иконку двухцветной через CSS невозможно. Один символ — один цвет.
Частично проблему с размером решают сервисы вроде IcoMoon или fontello.com: выбираешь только нужные иконки и скачиваешь подмножество шрифта. Тогда вес падает до 15–30 КБ. Но остальные проблемы никуда не деваются.
Иконочные шрифты сейчас оправданы, если ты работаешь внутри готовой дизайн-системы, которая уже использует конкретный шрифт (Material Design + Material Icons, например). Строить с нуля на шрифтах в 2026-м — сомнительное решение.
SVG inline — максимальный контроль
SVG прямо в HTML. Никаких ссылок на внешние файлы — весь код иконки вставляется в разметку:
<button>
<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true">
<path d="M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z"/>
</svg>
Найти
</button>
Главное преимущество — полный контроль через CSS. Можно красить отдельные части иконки, делать hover-эффекты с изменением нескольких цветов, запускать CSS-анимации на конкретных путях. Никакой другой метод столько не даёт.
Производительность хорошая: иконка уже в HTML, ноль дополнительных HTTP-запросов, рендерится сразу при парсинге DOM.
Доступность настраивается точно: можно добавить <title> внутри SVG, role="img", aria-labelledby — всё что нужно.
Но есть серьёзный минус: HTML-код раздувается. Если на странице 40 иконок и каждая занимает 8–12 строк SVG-кода — это +400 строк в разметке. Страница тяжелеет, читать её тяжелее, поддерживать — тем более.
Кешируется это плохо. SVG-код — часть HTML-документа, а HTML кешируется иначе, чем статические файлы: браузер проверяет актуальность при каждом запросе.
Ещё одна боль: если одна и та же иконка используется на десяти страницах сайта, её SVG-код дублируется в каждой. Поменял иконку в Figma — нужно найти и заменить все вхождения в коде.
Inline SVG стоит выбирать для иконок с анимацией, логотипов, декоративных элементов, где нужна нестандартная стилизация. И когда иконок мало — до 5–8 на страницу.
SVG-спрайты — золотая середина
Спрайт — это один SVG-файл, в котором все иконки хранятся как именованные символы через <symbol>. На странице ты ссылаешься на нужный символ через <use>.
Вот как выглядит файл icons.svg:
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-search" viewBox="0 0 24 24">
<circle cx="11" cy="11" r="8"/>
<path d="M21 21l-4.35-4.35"/>
</symbol>
<symbol id="icon-arrow" viewBox="0 0 24 24">
<path d="M5 12h14M12 5l7 7-7 7"/>
</symbol>
</svg>
Использование в HTML:
<svg width="24" height="24" aria-hidden="true">
<use href="/icons.svg#icon-search"/>
</svg>
Три строки вместо десяти. И при этом иконки кешируются браузером как обычный статический файл. Загрузил один раз — работает на всех страницах сайта.
Цвет меняется через currentColor: устанавливаешь color на родительском элементе — иконка подхватывает.
Есть ограничения. Через <use> нельзя достучаться CSS снаружи до отдельных путей внутри <symbol> — они изолированы в shadow DOM. Менять можно только базовые свойства: color, fill через currentColor, stroke. Для сложной стилизации спрайт не подходит.
Ещё одна ловушка: если спрайт лежит на другом домене (например, на CDN), браузер может заблокировать запрос из-за политики CORS. Спрайт должен быть на том же домене, что и сайт, или сервер должен отдавать правильные CORS-заголовки.
Инструментарий для генерации спрайтов: npm-пакет svg-sprite собирает спрайт автоматически из папки с SVG-файлами и подключается в Webpack или Vite. Настройка — один час работы.
Сравнение в цифрах
Реальный кейс: интерфейс с 40 иконками, каждая 24×24 пикселя.
| Метод |
Размер |
HTTP-запросы |
Кеш |
Гибкость стилей |
| Font Awesome полный |
~400 КБ |
1 шрифт |
Хороший |
Низкая |
| Font Awesome подмножество |
~20 КБ |
1 шрифт |
Хороший |
Низкая |
| SVG inline |
+10–15 КБ к HTML |
0 |
Плохой |
Максимальная |
| SVG-спрайт |
6–10 КБ |
1 файл |
Отличный |
Средняя |
SVG-спрайт выигрывает почти везде, кроме сценариев со сложной анимацией иконок.
Оптимизация SVG из Figma
Когда дизайнер экспортирует иконку из Figma, в файле обычно живёт лишний мусор: метаданные редактора, пустые группы, неоптимальные пути с лишними точками, абсолютные координаты там, где достаточно относительных.
Простой пример: иконка в 800 байт из Figma после оптимизации через SVGO становится 280 байт. Это 2–3x разница.
SVGO — стандартный инструмент для этого. Запускается из командной строки или подключается в сборщик. Дефолтные настройки убирают большую часть мусора.
Но осторожно: агрессивная оптимизация иногда ломает сложные иконки — удаляет атрибуты, без которых иконка рендерится неправильно. После обработки всегда проверяй визуально, особенно на сложных иконках с масками и градиентами.
Правило простое: прогоняй все SVG через SVGO перед добавлением в проект. Это привычка, которая экономит килобайты суммарно.
Доступность — то, о чём чаще всего забывают
Независимо от метода, иконки требуют правильной разметки для вспомогательных технологий.
Декоративная иконка рядом с текстом (дублирует его смысл — не читать):
<svg aria-hidden="true" focusable="false">...</svg>
Иконка как единственный элемент кнопки (без видимого текста):
<button aria-label="Поиск">
<svg aria-hidden="true" focusable="false">...</svg>
</button>
focusable="false" нужен для IE11 — без него SVG получает фокус клавиатуры отдельно от кнопки. В проектах без поддержки IE можно опустить, но хуже от него не будет.
Если иконка несёт самостоятельный смысл (не кнопка, а просто изображение без подписи), добавляй <title> внутри SVG:
<svg role="img" aria-labelledby="icon-title">
<title id="icon-title">Предупреждение</title>
<path d="..."/>
</svg>
currentColor — главный трюк со стилями
Самый удобный способ стилизовать SVG-иконки — использовать currentColor. Это специальное значение в SVG, которое наследует цвет текста (color) из CSS родительского элемента.
.btn {
color: #2563eb;
}
.btn:hover {
color: #1d4ed8;
}
<svg><path fill="currentColor" d="..."/></svg>
Иконка автоматически станет синей внутри кнопки и потемнеет при hover — ничего отдельно настраивать не нужно. Работает для inline SVG и спрайтов. Для шрифтов это происходит само по себе, потому что иконка — символ текста.
Как выбирать на практике
Если нужно быстро — и анимаций нет, и требования к стилизации простые — бери SVG-спрайт. Настройка занимает час, потом добавляешь иконки в папку и используешь через <use>. Один HTTP-запрос, отличный кеш, чистая разметка.
Если иконка анимированная или нужно менять цвет отдельных частей при hover — вставляй inline SVG. Таких иконок обычно немного.
Иконочный шрифт имеет смысл только если работаешь внутри дизайн-системы, которая уже на нём построена, или если нужно очень быстро прототипировать без сборщика.
В REEXY при разработке корпоративных сайтов и интернет-магазинов SVG-спрайт используется как основной подход — это оптимальный баланс производительности, удобства поддержки и гибкости. Inline SVG остаётся для логотипов и акцентных анимированных элементов.
Есть ещё вариант для React-проектов: библиотека SVGR конвертирует SVG в React-компоненты. Тогда иконка становится компонентом с props для размера и цвета. Удобно в больших SPA, но это уже отдельная история.
Итого: три сценария
Выбирай SVG-спрайт, если строишь продуктовый интерфейс, интернет-магазин или корпоративный сайт с набором из 20+ иконок. Производительность, кеширование, чистый код.
Выбирай inline SVG, если иконок мало или нужна анимация и сложная стилизация. Логотипы, декоративные иллюстрации, иконки с hover-эффектами на несколько цветов.
Выбирай иконочный шрифт, если работаешь в экосистеме, которая уже на нём построена, или нужен быстрый прототип без настройки сборщика.
Во всех случаях: SVGO для оптимизации файлов и aria-hidden с aria-label для доступности — это не опционально, это базовая гигиена.