Привет, Хабр! Меня зовут Артём Поморцев. Я фронтенд-разработчик компании «Криптонит» и хочу поделиться своим опытом создания набора иконок (icon pack).

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

Проблема

Наша проблема заключалась в том, что мы переходили на новый дизайн. Тогда мы работали с фреймворком blueprint.js, и он не всегда отвечал требованиям UX-дизайнеров. Также было желание сделать собственный пакет иконок, который можно было бы легко дополнять и изменять по мере необходимости.

Решение

Первоначально мы попробовали использовать другие пакеты иконок, такие как FontAwesome, Vue-Unicons и HeroIcons. Однако дизайнерам они тоже не подошли, поэтому мы решили подготовить собственный пакет иконок. Поначалу хотелось найти готовое программное решение, в которое можно добавить файлы SVG и билдить со спокойной душой. Этого не нашлось, поэтому мы решили собрать его из двух библиотек: svgtofont и SVGO.

1) svgtofont

svgtofont — это библиотека для генерации иконочных шрифтов из файлов SVG. Документация объёмная, поэтому расскажу лишь о самых интересных возможностях:

  • outSVGReact — передача из SVG в React-компонент;

  • outSVGReactNative — передача из SVG в компонент React Native;

  • outSVGPath — возможность конвертации SVG в CSS-полигон;

  • startUnicode — код символа, с которого стартует шрифт;

  • useCSSVars — возможность использования CSS-переменных.

Также svgtofont поддерживает свойства svgicons2svgfont.

Быстрая настройка для проекта (package.json)

С svgtofont возникли проблемы. Главная из них состояла в том, что иконки заполнялись, когда не следует, или вообще не отображались (об этом расскажу ниже).

2) SVGO

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

Быстрая настройка для проекта (package.json)

SVGO запускает под капотом оптимизацию файлов.

--folder ./svg — указывается входная папка.

-o или --output — выходной файл или папка (по умолчанию такая же, как и входная).

./svg_generated — папка с оптимизированными SVG-файлами.

 

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

В результате применения SVGO размер пакета уменьшился на 19%

Так в чём же была проблема с отображением иконок?

Причина этой проблемы — алгоритм, используемый для определения внутренней части фигуры. Алгоритм задаётся атрибутом fill-rule тега <path> внутри SVG. Значение по умолчанию: «nonzero». Есть ещё одно значение «evenodd», которое поддерживается редко.

Если вы просто удалите атрибут, направление пути d будет таким же. Поэтому нужно изменить направление путей самостоятельно. Вот как решить эту проблему:

1. Скачайте Fill Rule Editor:

2. Перетащите или вставьте значок SVG, шрифт которого выглядит странно, и откройте плагин:

3. Нажимаем на SVG:

4. А теперь, чтобы это исправить, нажмите на внутренний или внешний контур:

Проблема решена!

Полный билд сборки:

Результат:

Итоги:

Размер упакованного пакета: 485 Кб
Размер проекта после распаковки: 1.75 Мб
Количество файлов SVG: 400