Куда идем?

Ни один современный веб-дизайн не обходится сегодня без иконок. Они везде. Они всюду. Они на кнопках, фильтрах, сортировках. По ним мы понимаем значение элемента интерфейса мгновенно, не читая даже описание.

Бургер-меню, стрелки слайдера, избранное и корзина, сворачивание и разворачивание блока, перетаскивание – всем правят иконки.

В этой статье я расскажу просто, и в то же время подробно, про способы работы с SVG-иконками на вашем сайте.

SVG-иконки

Сегодня, говоря «иконка» я автоматически подразумеваю изображение в формате SVG. SVG – векторный формат. Он, фактически, стал стандартом для иконок. 

Почему SVG, а не jpg/png

Растровая графика – рисунок состоит из большого числа точек разного цвета (пикселей). Используется в фотографиях, артах нейросетей, пейзажах и других многоцветных изображениях с множеством деталей.

Векторная графика – рисунок описывается формулами или состоит из элементов, описанных математически. Используется в шрифтах, иконках, малоцветных изображениях.

Векторная графика обладает некоторыми важными преимуществами перед растровой, когда речь идет про иконки:

  • Она может быть масштабирована без потери качества
  • Она может легко менять цвет

Два этих преимущества играют решающее значение.

Вы можете сделать иконку в jpg или png – это будет работать. Раньше это было нормой. Но при этом вы лишитесь двух преимуществ, описанных выше. А как мы увидим дальше, они очень важны.

Где взять бесплатные SVG-иконки

Хорошо, мы хотим SVG, мы хотим «вектор». Делать их самостоятельно – ну такое…Долго, да и нужно обладать хотя бы какими-то дизайнерскими навыками.

Есть пара способов получить SVG-иконку, которая будет удовлетворять вашим потребностям.

Способ 1:

https://icon-sets.iconify.design/

Сохраните эту ссылку. Запомните эту ссылку. Повесьте эту ссылку в рамочку. Забудьте про FontAwesome.

Здесь собрана действительно большая библиотека бесплатных иконок. Каждая открывается. Каждая редактируется. Каждая копируется.

Iconufy

Если все-таки запрос ваш слишком специфичен, настолько, что его не может удовлетворить библиотека из многих тысяч готовых иконок, то используем план Б:

Способ 2:

Существуют программы/сервисы/плагины, которые способны преобразовать растровую графику в векторную.

Предположим, что нам нужна очень специфичная иконка, какой-нибудь шаговый двигатель. Такие иконки обычно используются для украшения категорий товаров каталога. Проблем с тем, чтобы найти изображение шагового двигателя в jpg или png нет никаких. А вот найти его образ в SVG может быть крайне непросто.

Давайте рассмотрим пример превращения:

Превращение растрового изображение в векторное

Сие изображение есть первая попавшаяся картинка из Википедии. И она же, превращенная мной в вектор автоматическими средствами в пару кликов. Что это за средства?

Самый простой вариант – использовать один из множества онлайн-конверторов. Просто пишите в поисковике запрос «convert jpg to svg» и выбираете наиболее понравившийся конвертер. На сегодняшний день их очень много.

Другой способ для тех, кому знакомо название Figma. Это программа/сервис для дизайнеров. Ее можно использовать бесплатно, если вам не нужна большая командная работа. В Figma существует множество плагинов. Для конвертации растровой графики в векторную вы можете использовать, например, следующие:

  • Image tracer – отличный плагин с настройками конвертации. К сожалению, стал платным, а число бесплатных использований ограничено. Одиночная лицензия стоит 10$, а также есть вариант с задержкой конвертации, но уже за 2$. В общем, если часто пользоваться, то можно и купить.
  • Quick tracing – аналогичный плагин, который конвертирует изображения. Настроек, как в первом, нет, но зато бесплатно.

Результаты на шаговом двигателе с картинки выше оба плагина выдали примерно одинаковые, как и онлайн сервисы, которые я пробовал.

Надеюсь, что с иконками все понятно и теперь, когда мы знаем, где ими можно разжиться, можно перейти к непосредственному их применению.

Что такое спрайты и зачем они нужны

Что такое спрайты

Отдельные иконки – это хорошо, просто, красиво. Но что делать, если в вашем шаблоне их предполагается много? Десять, пятьдесят, сто… Можно использовать их как отдельные изображения, а можно объединить в общее изображение и всегда использовать его. Такое общее изображение и будет называться спрайт.

Какие бывают спрайты (немного истории)

Спрайты бывают разные. Они быстро эволюционируют вместе с развитием web’а.

Сначала были растровые спрайты. Мы брали маленькие картинки, помещали их на одну большую. А дальше делали блок на странице, у которого были фиксированные размеры, и эта большая картинка являлась background’ом. Сдвигом этого фона на заданное количество пикселей по горизонтали и вертикали достигалась ситуация, когда с большой картинки была видна только маленькая иконка. По ссылке выше вы сможете подробно прочитать про данную технику.

Несколько позднее на смену растровым спрайтам пришли иконочные шрифты. Здесь уже использовались векторные SVG-иконки. Они объединялись в файл шрифта, который подключался к сайту. Далее достаточно было указать в CSS-стилях этот шрифт и специфичный символ, описывающий иконку в нем. Так иконка выводилась. Наиболее известный пример иконочного шрифта – FontAwesome. Он часто используется и сегодня. Подробное описание и пример работы вы найдете также по ссылке выше.

Ну и современный этап эволюции спрайтов – SVG-спрайты. Им посвящена эта статья.

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

Зачем нужны спрайты

В целом со спрайтами разобрались. Но возникает резонный вопрос: а зачем они вообще нужны? Почему не использовать отдельные картинки?

Ответ здесь не будет однозначным, т.к. также уходит своими корнями в ранний web.

Когда баллом правили растровые спрайты, основной их целью было ускорение загрузки страницы. Тогда все сайты работали по протоколу HTTP первой версии, который предполагает последовательную загрузку ресурсов страницы. Это означает, что все файлы, подключенные к странице, загружались не сразу, а последовательно, один за другим. Для каждого файла устанавливалось соединение, потом была передача.

Нетрудно догадаться, что в случае с последовательной загрузкой ресурсов страница загружалась тем дольше, чем больше на ней было элементов. Иконки же – их много. Тогда и пригодились растровые спрайты.

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

Спрайты векторные давали ту же экономию, до появления протокола HTTP второй версии, где загрузка ресурсов страницы шла уже параллельно. Начиная с перехода на вторую версию HTTP, спрайты уже не имели смысла, как средство оптимизации скорости страницы. Но зато они стали средством удобства разработчиков.

Иконочный шрифт удобен тем, что, будучи подключенным один раз, он позволяет легко вставить иконку, используя CSS-классы в разметке на странице, а главное, позволяет применять к ней некоторые CSS-стили, такие как изменение цвета (актуально при наведении курсора), размера.

SVG-спрайт

Как уже было сказано выше, SVG-спрайт – это SVG-файл, содержащий в себе код других SVG-файлов в заданном формате. Рассмотрим основные преимущества такого подхода:

  • Вы можете легко добавлять и убирать иконки из файла спрайта, благодаря возможности его редактировать (вопрос редактирования дискуссионный, как вы увидите дальше)
  • Вы можете вставлять иконки из спрайта в html-разметку короткими кусочками кода
  • Вы можете влиять на вставленные иконки через CSS
  • Файл SVG-спрайта кэшируется браузером и не будет загружаться повторно без необходимости.
  • Файл SVG-спрайта поддается сжатию и оптимизации.

Код спрайта и добавленных в него изображений

Что ж, ближе к делу. Мы хотим создать SVG-спрайт. Для этого достаточно создать текстовый файл, переименовав его расширение в .svg (для примера назовем его my_sprite.svg), и добавить внутрь следующий базовый код:

<svg></svg>

Собственно, оболочка готова. Для добавления в спрайт иконок (любых SVG-изображений) мы должны:

  • Скопировать код иконки.
  • Изменить в этом коде открывающий и закрывающий тег svg на тег symbol
  • Добавить к тегу symbol уникальный идентификатор id, который и будет затем вызывать данную иконку из спрайта
  • Вставить получившийся код в файл спрайта между тегами svg.

Давайте посмотрим на примере:

Возьмем с Iconify пару иконок, а также возьмем наш шаговый двигатель, преобразованный в SVG.

Вот они:

<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 15 15"><path fill="none" stroke="currentColor" d="m2.5 2.5l2 3m8-3l-2 3M4 9.5h1m5 0h1m-9.5 3v-2a6 6 0 1 1 12 0v2z"/></svg>

<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 15 15"><path fill="currentColor" d="M8 13a2 2 0 0 0 2-2H9a1 1 0 0 1-1 1H6.5v1z"/><path fill="currentColor" fill-rule="evenodd" d="M7.5 15a5.14 5.14 0 0 1-.543-.029L7 15H1V6h.019A6.5 6.5 0 0 1 14 6.5V15zM8.974 4.9l1.3.086A5.951 5.951 0 0 1 11.503 7H4.207a5.616 5.616 0 0 1 4.767-2.1M9.085 8h2.71l.04.196a4 4 0 0 1 .07.804H10.5a1.5 1.5 0 0 1-1.415-1m1.415 2h1.286a8.016 8.016 0 0 1-.524 1.556a4.116 4.116 0 0 1-7.524 0A6.23 6.23 0 0 1 3.254 10H4.5a2.5 2.5 0 0 0 2.45-2h1.1a2.5 2.5 0 0 0 2.45 2m-6-1H3.235c.032-.23.09-.453.18-.669c.048-.112.099-.223.153-.331h2.347A1.5 1.5 0 0 1 4.5 9" clip-rule="evenodd"/></svg>

<svg width="294" height="182" viewBox="0 0 294 182" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M122.5 0.499997C122 0.699997 111.2 3.8 98.5 7.5C85.9 11.1 75.2 14.4 74.8 14.8C74 15.6 74.9 15.8 80.8 16.2C82.5 16.4 84 16.8 84 17.2C84 17.6 84.8 17.7 85.8 17.3C87.4 16.7 87.4 16.8 85.8 18.7C84.4 20.2 84 22.4 84 28.3C84 33.2 83.6 36.1 82.8 36.6C81.1 37.7 78 37.8 78 36.9C78 36.4 77.4 36.3 76.6 36.6C75.8 36.9 74.9 36.6 74.5 36.1C74.2 35.5 73.3 35.3 72.7 …
… 162.7C204.1 163.5 202 168.7 202 173C202 175.3 202.3 177 202.8 176.8C203.2 176.6 205.4 175.5 207.7 174.4C211.5 172.7 212 172.1 212 169.2C212 163.5 210 161.2 206.2 162.7Z" fill="black"/>
</svg>

Код иконки двигателя большой и в примере я его обрезал.

Теперь мы должны заменить в кодах иконок тег svg на symbol и добавить уникальные id к каждому тегу symbol. Делаем:

<symbol id="robot" xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 15 15"><path fill="none" stroke="currentColor" d="m2.5 2.5l2 3m8-3l-2 3M4 9.5h1m5 0h1m-9.5 3v-2a6 6 0 1 1 12 0v2z"/></symbol>

<symbol id="girl" xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 15 15"><path fill="currentColor" d="M8 13a2 2 0 0 0 2-2H9a1 1 0 0 1-1 1H6.5v1z"/><path fill="currentColor" fill-rule="evenodd" d="M7.5 15a5.14 5.14 0 0 1-.543-.029L7 15H1V6h.019A6.5 6.5 0 0 1 14 6.5V15zM8.974 4.9l1.3.086A5.951 5.951 0 0 1 11.503 7H4.207a5.616 5.616 0 0 1 4.767-2.1M9.085 8h2.71l.04.196a4 4 0 0 1 .07.804H10.5a1.5 1.5 0 0 1-1.415-1m1.415 2h1.286a8.016 8.016 0 0 1-.524 1.556a4.116 4.116 0 0 1-7.524 0A6.23 6.23 0 0 1 3.254 10H4.5a2.5 2.5 0 0 0 2.45-2h1.1a2.5 2.5 0 0 0 2.45 2m-6-1H3.235c.032-.23.09-.453.18-.669c.048-.112.099-.223.153-.331h2.347A1.5 1.5 0 0 1 4.5 9" clip-rule="evenodd"/></symbol>

<symbol id="engine" width="294" height="182" viewBox="0 0 294 182" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M122.5 0.499997C122 0.699997 111.2 3.8 98.5 7.5C85.9 11.1 75.2 14.4 74.8 14.8C74 15.6 74.9 15.8 80.8 16.2C82.5 16.4 84 16.8 84 17.2C84 17.6 84.8 17.7 85.8 17.3C87.4 16.7 87.4 16.8 85.8 18.7C84.4 20.2 84 22.4 84 28.3C84 33.2 83.6 36.1 82.8 36.6C81.1 37.7 78 37.8 78 36.9C78 36.4 77.4 36.3 76.6 36.6C75.8 36.9 74.9 36.6 74.5 36.1C74.2 35.5 73.3 35.3 72.7 …
… 162.7C204.1 163.5 202 168.7 202 173C202 175.3 202.3 177 202.8 176.8C203.2 176.6 205.4 175.5 207.7 174.4C211.5 172.7 212 172.1 212 169.2C212 163.5 210 161.2 206.2 162.7Z" fill="black"/>
</symbol>

И последний шаг. Вставляем получившийся код в наш заготовленный SVG-файл. Его итоговый вариант будет таким:

<svg>
<symbol id="robot" xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 15 15"><path fill="none" stroke="currentColor" d="m2.5 2.5l2 3m8-3l-2 3M4 9.5h1m5 0h1m-9.5 3v-2a6 6 0 1 1 12 0v2z"/></symbol>
<symbol id="girl" xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 15 15"><path fill="currentColor" d="M8 13a2 2 0 0 0 2-2H9a1 1 0 0 1-1 1H6.5v1z"/><path fill="currentColor" fill-rule="evenodd" d="M7.5 15a5.14 5.14 0 0 1-.543-.029L7 15H1V6h.019A6.5 6.5 0 0 1 14 6.5V15zM8.974 4.9l1.3.086A5.951 5.951 0 0 1 11.503 7H4.207a5.616 5.616 0 0 1 4.767-2.1M9.085 8h2.71l.04.196a4 4 0 0 1 .07.804H10.5a1.5 1.5 0 0 1-1.415-1m1.415 2h1.286a8.016 8.016 0 0 1-.524 1.556a4.116 4.116 0 0 1-7.524 0A6.23 6.23 0 0 1 3.254 10H4.5a2.5 2.5 0 0 0 2.45-2h1.1a2.5 2.5 0 0 0 2.45 2m-6-1H3.235c.032-.23.09-.453.18-.669c.048-.112.099-.223.153-.331h2.347A1.5 1.5 0 0 1 4.5 9" clip-rule="evenodd"/></symbol> <symbol id="engine" width="294" height="182" viewBox="0 0 294 182" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M122.5 0.499997C122 0.699997 111.2 3.8 98.5 7.5C85.9 11.1 75.2 14.4 74.8 14.8C74 15.6 74.9 15.8 80.8 16.2C82.5 16.4 84 16.8 84 17.2C84 17.6 84.8 17.7 85.8 17.3C87.4 16.7 87.4 16.8 85.8 18.7C84.4 20.2 84 22.4 84 28.3C84 33.2 83.6 36.1 82.8 36.6C81.1 37.7 78 37.8 78 36.9C78 36.4 77.4 36.3 76.6 36.6C75.8 36.9 74.9 36.6 74.5 36.1C74.2 35.5 73.3 35.3 72.7 … … 162.7C204.1 163.5 202 168.7 202 173C202 175.3 202.3 177 202.8 176.8C203.2 176.6 205.4 175.5 207.7 174.4C211.5 172.7 212 172.1 212 169.2C212 163.5 210 161.2 206.2 162.7Z" fill="black"/> </symbol>
</svg>

На этом все, можно загружать файл на сервер.

Как вызвать отдельное изображение из спрайта

С вызовом изображений все очень просто:

<svg><use xlink:href="/my_sprite.svg#robot"></use></svg>
<svg><use xlink:href="/my_sprite.svg#girl"></use></svg>
<svg><use xlink:href="/my_sprite.svg#engine"></use></svg>

Обычно лучше добавить еще к тегу SVG в коде вызова какой-то класс, чтобы можно было добавлять иконкам общие стили, приводящие любое вызванное изображение к базовому формату.

Давайте теперь посмотрим, как работает спрайт и код вызова вживую (смотрите html-разметку страницы через веб-инспектор):

Формирование SVG-спрайта

Чисто технически с созданием и использованием SVG-спрайта мы разобрались. Осталось разобрать еще один важный вопрос: как лучше формировать SVG-спрайт, когда иконок много? Ответ на этот вопрос может быть спорным. Опишу все варианты, а также их достоинства и недостатки.

Формирование SVG-спрайта автоматически с помощью сборки

Типичный программист отличается умом и сообразительностью ленью и склонностью все автоматизировать. Досталось здесь и SVG-спрайтам.

Положим, есть у нас набор иконок, штук 50. Нужно собрать их в спрайт. Делать это вручную… Можно, но кажется, что долго (читаем абзац выше). Нужно автоматизировать.

Как происходит автоматизация? Берется один из автоматических сборщиков и плагин/модуль/пакет к нему, который собирает спрайты. Делается конфигурационный файл, в котором указываются все необходимые исходные данные. Иконки помещаются в заданную папку. А дальше… Остается нажать волшебную кнопку и спрайт соберется сам.

Если вам знакомы такие сочетания букв как npm, Webpack, Grunt, Gulp, то дам несколько ссылок на условно готовые инструменты. Почему «условно»? По моему скромному мнению, это путь «долго запрягать, да быстро ехать». Запрягать там можно действительно долго, но если уже не первый раз, то это все для вас:

https://github.com/svg-sprite/svg-sprite

https://github.com/JetBrains/svg-sprite-loader?tab=readme-ov-file

Тру-программисты непременно будут использовать нечто подобное. В моем же понимании, времени на то, чтобы заставить работать эти адские машины, может уйти больше, чем собрать спрайт вручную.

Здесь нужно руководствоваться здравой логикой:

  • Если у вас очень большое количество иконок, которые, к тому же, часто изменяются, а также вы занимаетесь крупным проектом, который в любом случае предполагает IDE и сборку, то использование автоматических сборщиков будет оправданным.
  • Если иконок у вас немного, а проект обновляется силами одного человека с периодическими изменениями, то стоит посмотреть в сторону следующий двух способов формирования SVG-спрайта.

Формирование SVG-спрайта автоматически с помощью сервисов

Положим, что вы не тру-программист (значит, вероятно, false-программист ;-)) и заморачиваться длительной настройкой сборщика не хотите. При этом не хотите и формировать спрайт руками. В общем, надо быстро и один раз.

В таком случае вам подойдет один из многих готовых сервисов генерации спрайтов, которые можно легко найти в Интернете по фразе «SVG-sprite generator».

Как это работает? Загружаете в сервис группу иконок –> Жмете кнопочку –> Получаете готовый спрайт. Вот один из таких сервисов:

https://products.aspose.app/svg/ru/svg-sprite-generator

Каковы недостатки такого способа формирования спрайта?

Основной недостаток – обновление спрайта. Если вы не умеете делать это вручную, то при добавлении или изменении даже одной иконки придется перегенерировать спрайт заново. Снова и снова.

Если у вас изначально большое количество иконок для спрайта, то можно воспользоваться один раз таким сервисом, а дальше…

Ручное формирование SVG-спрайта

Дальше можно работать со спрайтом вручную. Может показаться странным, но мне такой подход показался наиболее удобным.

Как работать с SVG-спрайтом вручную:

  • Открыть файл спрайта через текстовый редактор
  • Добавить/изменить/удалить отдельные иконки в файле
  • Сохранить файл

Да, так просто. Это, собственно, все то, что вы делаете с сайтом, когда работаете с его кодом.

Единственный совет: чтобы код файла спрайта был более читаемым, лучше убирать для каждой отдельной иконки переносы строк (делать ее в одну строку), а между иконками добавлять по два переноса. В таком случае код вашего спрайта будет выглядеть примерно так, как показано в нашем живом примере выше. Что тут сложного? Ничего. Это максимально простой формат.

Добавлю еще несколько преимуществ ручного наполнения спрайта для верстальщика:

  • Обычно, если у вас есть готовый дизайн, иконки в нем разбросаны по всем страницам. Собирать их в единый набор – уже утомительное занятие. Вам придется выгружать их, сохранять, потом создавать спрайт. Или же, если вы делаете спрайт вручную, нужно просто скопировать из дизайн-макета SVG-код иконки и вставить его в файл спрайта. На этом всё. Никакой дополнительной работы с файлами!
  • Иконки можно добавлять в спрайт постепенно, в процессе верстки дизайна. Увидели новую иконку, которой еще нет в спрайте? Скопировали ее код, добавили в спрайт, тут же вывели на странице и оформили. Получается быстро и удобно.
  • Можно придумывать названия иконкам прямо при добавлении в спрайт. Называть их так, как понятно вам, а не так, как оно было обозвано в дизайне.
  • Можно править иконки прямо на ходу. Если вы хотя бы немного смыслите в SVG-разметке, то можете быстро изменить код иконки, сделав ее, например, жирнее, или добавив в нее дополнительные элементы.

Заключение

SVG-спрайты – это, в первую очередь, удобство для разработчика. Их легко создавать и обновлять. Для этого не требуется повторная генерация – достаточно отредактировать файл в любом текстовом редакторе. Если вы до сих пор не применяете эту технику, то настоятельно рекомендую попробовать. Жить станет проще, жить станет веселее.

Об авторе
Wedal
(Виталий). Веб-разработчик полного цикла (Full Stack). Создатель и автор сайта Wedal.ru.
Основной профиль – создание сайтов и расширений на CMS Joomla.
Добавить комментарий