Создание SVG спрайтов (sprite) на примере иконок Font Awesome

Пока делаю это для одного сайта, решил и пост на эту тему написать, т. к. напоминалка-шпаргалка для самого себя на будущее… Описывать не буду почему это нужно и для чего. Кто знает — найдет в посте что-то полезное для себя.
В общем начнем. Всё на самом деле делается довольно просто: нужно создать один svg файл из нескольких, чтобы не загружать много файлов самого шрифта, это не не очень прям сильно, но сделает загрузки страницы быстрее, и пользователям от скорости загрузки сайта будет комфортнее им пользоваться…
- Создаём спрайт вручную или любым онлайн сервисом. Например, у меня есть минимальный SVG Sprite Generator, который делает своё дело нормально, чтобы вручную не собирать все иконки. Просто кидаем все нужные нам иконки и создаем svg sprite.
- Скачиваем его и кидаем в папку, например, {THEME}/images/fa-sprite.svg.
- Теперь остается только выводить нужные иконки. Строка вывода нужной иконки будет выглядеть так:
<svg class="icons" width="24" height="24"> <use xlink:href="{THEME}/images/fa-sprite.svg?21#bars"></use> </svg>или проще в одну строку:
<svg class="icons" width="24" height="24"><use xlink:href="{THEME}/images/fa-sprite.svg?21#bars"></use></svg>Здесь мы указали путь к нашему спрайту и название файла которое было, в данном случае — это был файл bars.svg. Название может быть любым, в спрайте оно указывается в id symbol:
<symbol id="bars" viewBox="0 0 448 512"> <path d="M0 88C0 74.7 10.7 64 24 64l400 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L24 112C10.7 112 0 101.3 0 88zM0 248c0-13.3 10.7-24 24-24l400 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L24 272c-13.3 0-24-10.7-24-24zM448 408c0 13.3-10.7 24-24 24L24 432c-13.3 0-24-10.7-24-24s10.7-24 24-24l400 0c13.3 0 24 10.7 24 24z"/> </symbol>назвать иконку вы можете как угодно, в генераторе есть разные варианты генерации ID символа.
- Всё готово, создали спрайт и раскидали по сайту иконки в нужные места, настроили CSS чтобы они не отличались от вывода fontawesome иконок…
Основные CSS стили для SVG иконок (как Font Awesome):
/* Базовые стили для SVG иконок (как Font Awesome) */
.icons {
display: inline-block;
fill: currentColor; /* Наследует цвет текста */
stroke: currentColor;
/* Выравнивание как у текста */
vertical-align: -0.125em; /* Точное выравнивание по baseline */
/* Размер как у текста (наследует от родителя) */
width: 1em;
height: 1em;
/* Позиционирование */
position: relative;
top: 0.125em; /* Корректировка позиции */
/* Гарантия отображения */
overflow: hidden;
flex-shrink: 0;
}
/* Для иконок внутри кнопок и ссылок */
button .icons,
a .icons {
margin-right: 0.5em; /* Отступ справа, как у FA */
}
/* Размеры как у Font Awesome */
.icons-xs { font-size: 0.75em; } /* 12px при базовом 16px */
.icons-sm { font-size: 0.875em; } /* 14px */
.icons-md { font-size: 1em; } /* 16px (по умолчанию) */
.icons-lg { font-size: 1.25em; } /* 20px */
.icons-xl { font-size: 1.5em; } /* 24px */
.icons-2x { font-size: 2em; } /* 32px */
.icons-3x { font-size: 3em; } /* 48px */
/* Вращение (как у FA) */
.icons-rotate-90 { transform: rotate(90deg); }
.icons-rotate-180 { transform: rotate(180deg); }
.icons-rotate-270 { transform: rotate(270deg); }
.icons-flip-horizontal { transform: scaleX(-1); }
.icons-flip-vertical { transform: scaleY(-1); }
/* Анимация вращения (как fa-spin) */
.icons-spin {
animation: icon-spin 2s infinite linear;
}
@keyframes icon-spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Фиксированная ширина (как fa-fw) */
.icons-fw {
width: 1.25em;
text-align: center;
}
/* Для списков (как fa-ul/fa-li) */
.icons-list {
padding-left: 0;
list-style-type: none;
}
.icons-list li {
display: flex;
align-items: flex-start;
margin-bottom: 0.5em;
}
.icons-list .icons {
margin-right: 0.5em;
margin-top: 0.125em; /* Корректировка для выравнивания */
}
/* Stack иконок (как fa-stack) */
.icons-stack {
position: relative;
display: inline-block;
width: 2em;
height: 2em;
line-height: 2em;
vertical-align: middle;
}
.icons-stack-1x,
.icons-stack-2x {
position: absolute;
left: 0;
width: 100%;
text-align: center;
}
.icons-stack-1x { font-size: 1em; }
.icons-stack-2x { font-size: 2em; }
/* Pull иконок (как fa-pull-left/right) */
.icons-pull-left {
float: left;
margin-right: 0.3em;
}
.icons-pull-right {
float: right;
margin-left: 0.3em;
}
/* Границы (как fa-border) */
.icons-border {
padding: 0.2em 0.25em 0.15em;
border: 0.08em solid currentColor;
border-radius: 0.1em;
}
Цвета для иконок лучше прописывать так:
/* Базовый класс - только настройки наследования */
.icon {
fill: currentColor; /* Наследует цвет от свойства color */
stroke: currentColor; /* Наследует цвет от свойства color */
color: inherit; /* Наследует цвет от родителя */
}
/* Цветовые классы */
.icons-green {
color: #4CAF50; /* Только меняем color, fill/stroke подхватят автоматически */
}
.icons-red {
color: #F44336;
}
.icons-blue {
color: #2196F3;
}
.icons-orange {
color: #FF9800;
}
.icons-purple {
color: #9C27B0;
}
.icons-gray {
color: #9E9E9E;
}
.icons-black {
color: #000000;
}
.icons-white {
color: #FFFFFF;
}
Возможные проблемы…
- В данный момент столкнулся с проблемой отображения иконки favorites: при добавлении в избранное — иконка теряется. Решение найдено
ищется…:⚠️ Войдите в аккаунт для доступа к контенту - Не все иконки могут быть 100% идентичными тем, которые отображались через fa- иконки.
И на последок, ещё решил расписать, как вручную собирать спрайты, в этом нет ничего сложного, когда иконок не много — это сделать не долго, но когда иконок 10+ — процесс может занять много времени, чем это займет с онлайн генератором спрайтов.
- Кидаем в кучу нужные нам спрайты.
- Открываем первый в notepad++ и видим, например, такой код:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><path d="M0 88C0 74.7 10.7 64 24 64l400 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L24 112C10.7 112 0 101.3 0 88zM0 248c0-13.3 10.7-24 24-24l400 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L24 272c-13.3 0-24-10.7-24-24zM448 408c0 13.3-10.7 24-24 24L24 432c-13.3 0-24-10.7-24-24s10.7-24 24-24l400 0c13.3 0 24 10.7 24 24z"/></svg>или в более читаемом виде:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> <!--! Font Awesome Pro 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --> <path d="M0 88C0 74.7 10.7 64 24 64l400 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L24 112C10.7 112 0 101.3 0 88zM0 248c0-13.3 10.7-24 24-24l400 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L24 272c-13.3 0-24-10.7-24-24zM448 408c0 13.3-10.7 24-24 24L24 432c-13.3 0-24-10.7-24-24s10.7-24 24-24l400 0c13.3 0 24 10.7 24 24z"/> </svg> - Нам нужен только path и viewBox.
- Создаем новый файл, шаблона:
<svg width="0" height="0" class="hidden"> <!-- Иконка 1 --> <symbol id="bars" viewBox="0 0 448 512"> <path d="M0 88C0 74.7 10.7 64 24 64l400 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L24 112C10.7 112 0 101.3 0 88zM0 248c0-13.3 10.7-24 24-24l400 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L24 272c-13.3 0-24-10.7-24-24zM448 408c0 13.3-10.7 24-24 24L24 432c-13.3 0-24-10.7-24-24s10.7-24 24-24l400 0c13.3 0 24 10.7 24 24z"/> </symbol> <!-- Иконка 2 --> <symbol id="search" viewBox="0 0 512 512"> <path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376C296.3 401.1 253.9 416 208 416 93.1 416 0 322.9 0 208S93.1 0 208 0 416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"/> </symbol> </svg> - Прописываем все иконки указывая уникальные ID.
- В CSS нужно добавить:
.hidden { position: absolute; width: 0; height: 0; overflow: hidden; /* или display: none; но position: absolute лучше */ } - Так собираете все нужные иконки в один файл, и потом выводите их, как указано выше.
PS Подключайте через <use xlink:href="sprite.svg#icon-id"> для лучшего кэширования и уменьшения HTML кода. Да и HTML шаблон потом будет более удобен в чтении кода, нежели он будет забит SVG иконками, которые добавлены прямо в код.