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

Недостатки иконочных шрифтов
Как мы обсуждали в предыдущей части, существует несколько способов использования собственных иконок в проекте, и один из них — шрифт с иконками.
Иконочные шрифты — лучшие!
Их очень легко сгенерировать, использовать и кастомизировать. Они имеют широкую поддержку в браузерах, а код выглядит максимально чистым. Лично для меня это всегда первый выбор. Но, как и всё в этом мире, они — не идеальны и самое разочаровывающая часть — они не поддерживают более одного цвета.
Так как они основаны на OpenType / TrueType, они поддерживают только монохромные глифы — по сути, фигура, залитая одним цветом. А браузер применяет свойство color из CSS ко всему глифу целиком.
Если же у вас стоит задача использовать многоцветные иконки, есть два варианта:
использовать более продвинутые форматы, например
OpenType-SVG
илиCOLR/CPAL
, но их поддержка в браузерах пока ограничена;или воспользоваться «двухцветными иконками» (Duotone icons) — подход, который применяет Font Awesome, позволяющий поддерживать два цвета и управлять ими через CSS.
Двухцветные иконки

Такое решение — это тот же самый шрифт с иконками, но каждый глиф содержит не одну, а две фигуры, объединённые в одну иконку. Таким образом, вы можете менять font-size
и color
через псевдоэлементы: before
и after
, как вы обычно это делаете с одним псевдоэлементом before
.
.fa-duotone {
font-family: "Font Awesome 6 Duotone";
}
.fa-house::before {
content: "\f015";
}
.fa-duotone.fa-house::after {
content: "\f015\f015";
}
Это довольно простая идея, которая выглядит отлично!
Так как я не нашёл сторонних библиотек, которые поддерживают это «из коробки», если вы захотите использовать такой подход, придётся делать всё вручную:
разделить каждую иконку на 2 фигуры;
сгенерировать новый иконочный шрифт из SVG файлов;
модифицировать CSS-стили, чтобы объединить две фигуры в одну иконку с помощью псевдоэлементов.
Это не самое удобное решение, так как оно занимает много времени, и именно поэтому я предлагаю обратить внимание на SVG-спрайты.
SVG-спрайты
Идея использовать один общий спрайт для объединения небольших графических элементов, таких как иконки, не нова. Я помню, лет 15 назад фронтенд-разработчики использовали спрайты для тех же целей, но в другом формате — это было PNG изображение, которое содержало множество мелких графических элементов, и позже их можно было показать в проекте, используя свойство background-position
.
Плюс очевиден — пользователю нужно загрузить только один файл вместо множества, что могло значительно ускорить загрузку. Минус — всё приходилось делать вручную:
иметь отдельный PSD-файл с иконками;
добавлять / перемещать / удалять иконки вручную;
показывать изображения только как фоновые, а не через тег
<img>
;запоминать и вручную указывать позицию каждой иконки в файле.

С SVG-спрайтом вам не нужно делать ничего из этого! Подход тот же: один файл, много иконок и никаких недостатков. Каждая иконка добавляется в виде тега <symbol>
с определённым свойством id
, которое затем можно использовать где угодно с помощью тега <use>
. И поскольку существует множество сторонних библиотек, которые могут с этим работать, вы можете автоматизировать весь процесс.
И, кстати, я забыл упомянуть: никаких ограничений по цвету или размеру — вы можете использовать любые иконки, какие захотите. Звучит здорово, не так ли?
Структура папок
Чтобы правильно организовать исходные изображения и готовые SVG-спрайты, вам нужно создать две дополнительные папки — icons-sprite
и sprites
— в /src/assets/
.
После этого ваша структура будет выглядеть так:
/src
/assets
/fonts
/icons
/icons-sprite
/sprites
/styles
/_
/common
/components
/forms
├── _btn.scss
/mixins
/variables
├── _bootstrap.scss
├── _palette.scss
├── variables.scss
/vendor
├── app.scss
├── vendor.scss
styles.scss
Подготовка изображений

Никакой специальной подготовки изображений не требуется. Вам просто нужно поместить все исходные SVG иконки в папку /icons-sprite
. Эти изображения должны иметь размер и цвет, которые вам нужны в проекте, так как изменять эти параметры позже будет гораздо сложнее.
Пакет Svg2sprite-cli
Существует несколько отличных сторонних библиотек, которые можно использовать для генерации SVG-спрайта из SVG файлов, но я уже давно использую эту и могу её рекомендовать — Svg2sprite. Так как это CLI-интерфейс соответствующей библиотеки, его нужно установить глобально.
npm i -g svg2sprite-cli
После этого добавьте следующую команду в файл package.json
, чтобы можно было сгенерировать SVG-спрайт:
...
"icon:sprite": "svg2sprite ./src/assets/icons-sprite ./src/assets/sprites/icons.svg"
...
Вот и всё!
Теперь, когда вы запускаете команду yarn icon:sprite
, она возьмёт все SVG файлы из папки /icons-sprite
и создаст спрайт icons.svg
.
Пакет Ng-svg-icon-sprite
Последний шаг — подключить пакет ng-svg-icon-sprite
в проекте. Он используется для отображения выбранной иконки из созданного спрайта.
yarn add ng-svg-icon-sprite --dev
Затем добавьте импорт в файл app.config.ts
:
import { IconSpriteModule } from 'ng-svg-icon-sprite';
...
@NgModule({
...
providers: [
importProvidersFrom(
IconSpriteModule.forRoot({ path: 'assets/sprites/icons.svg' })
),
},
...
})
Таким образом, мы задаём единый путь для всех иконок, и вы сможете использовать их в любом месте. Конечно, нужно импортировать этот модуль и в сам компонент:
import { Component } from '@angular/core';
import { IconSpriteModule } from 'ng-svg-icon-sprite';
@Component({
selector: 'app-hero',
imports: [IconSpriteModule],
templateUrl: './hero.component.html',
styleUrl: './hero.component.scss',
})
export class HeroComponent {}
<svg-icon-sprite [src]="'purchase-done'"></svg-icon-sprite>
Для любых дополнительных параметров, которые можно использовать, пожалуйста, обратитесь к официальной документации.
И в самом конце нужно добавить папку sprites
в assets проекта. В файле angular.json
внесите изменения начиная с 29-й
строки:
...
"assets": [
"src/assets/fonts/",
"src/assets/sprites/",
{
"glob": "**/*",
"input": "public"
}
],
...
Заключение
Сегодня мы рассмотрели, как создать SVG-спрайт из SVG иконок и интегрировать его в Angular проект. В итоге у вас есть:
дополненная структура папок для организации исходных файлов иконок и итогового SVG-спрайта;
два дополнительных пакета:
Svg2sprite-cli
(установлен глобально) иNg-svg-icon-sprite
(добавлен локально в проект);дополнительная команда
icon:sprite
вpackage.json
, которая генерирует для вас SVG-спрайт.
В следующих статьях мы разберём основные принципы разработки адаптивного дизайна. Следите за обновлениями!