Иконки — это мелочь, которая не мелочь. Неправильный выбор метода замедляет страницу, ломает доступность для людей со скринридерами и делает поддержку мучительной через полгода. Три основных подхода сейчас: иконочные шрифты, 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 для доступности — это не опционально, это базовая гигиена.