Способы генерации SVG-спрайтов на примере библиотеки svg-sprite
Недавно я решал задачу организовать все SVG-файлы, используемые в проекте, в виде одного спрайта. До этого мне приходилось использовать самописное решение для такой задачи. На этот раз я решил воспользоваться популярной библиотекой svg-sprite, однако был сильно удивлен сколько разных способов создания она предлагает. Какой-то единой статьи где были разобраны все способы я не нашел, вся информация была разбросана по блогам и отдельным публикациям. Поэтому я решил собрать доступные в библиотеке способы для генерации спрайтов в одном месте, попутно проанализировав их преимущества и недостатки. Итак, поехали.
Режим CSS
Данный режим очень похож на привычный всем способ генерации спрайтов из картинок. Все файлы склеиваются в один, полученный файл ставится в качестве фона блока, а нужная иконка выбирается за счет смещения этого фона.
Пример использования будет выглядеть так
ei-archive
и соответствующий CSS-код
.svg-ei-archive {
background: url("svg/sprite.css.svg") 12.5% 0 no-repeat;
width: 50px;
height: 50px;
}
Приятно особенностью svg-sprite
является возможность задать в каком виде вы хотите получить стили — в виде чистого CSS или под препроцессоры LESS, SASS, Stylus. Немного поигравшись с шаблонами вывода, можно настроить вывод иконок в виде миксинов и генерировать код только тогда, когда он действительно нужен.
Преимущества: метод просто и понятен каждому, кто до этого работал со спрайтами.
Недостатки: невозможно указывать произвольные размеры, управлять цветом иконки. Не получится использовать в теге img
Режим defs
Этот режим использует тег defs, внутри которого объявляется элементы для дальнейшего использования. Каждому элементу присваивается id, по которому этот элемент будет вызван в теге use.
Пример использования
Для того чтобы use
из примера смог отрендерить элемент, SVG с defs
должен быть также включен в тело документа. Стандартом допускается использовать внешний файлов в xlink:href
, однако это не поддерживается всеми версиями Internet Explorer. К счастью, существует полифил svg4everybody, который решает эту проблему.
Преимущества: Метод хорош тем, что предоставляет вам контроль над встраиваемой иконкой через CSS или атрибуты. Вы сможете легко менять ее размеры или цвет.
Недостатки: Скорее всего потребуется некий механизм (макрос, хелпер, функция), который будет генерировать код вставки иконки. При генерации приходится указывать атрибут viewBox
и размеры. Согласно спецификации элементы внутри defs
не должны отображаться, поэтому нельзя будет визуально оценить как выглядят спрайты после оптимизации. Впрочем, svg-sprite
помогает в этом и может создать файл с образцами всех иконок.
В настоящее время использовать этот метод нет смысла, его улучшенной версией является Режим symbol.
Режим symbol
Принцип работы этого режима аналогичен предыдущему, но для задания элементов используется тег symbol. Этот элемент, согласно спецификации, может содержать атрибут viewBox
, поэтому отпадает необходимость указывать его при использовании заданного символа. Также элементы, созданные с использованием symbol
, отображаются при рендере, что упрощает визуальный контроль созданных спрайтов. В остальном применение этого метода не отличается от Режима defs.
Пример использования
Преимущества: Аналогично предыдущему режиму (легкая смена цвета и размеров).
Недостатки: Вам также понадобится вспомогательный механизм для вставки иконок. Однако, прочих недостатков метода defs этот режим лишен.
Режим view
В основе этого метода лежит возможность создания именованных областей просмотра для вашего документа в самом документе. Делается это с помощью тега view. Созданный таким образом спрайт можно использовать двумя способами.
Как обычную фоновую картинку из первого режима
ei-archive
и как отдельное изображение, встраиваемое с помощью идентификаторов фрагмента (fragment identifiers)
:root>svg {display:none}
:root>svg:target {display:block}
Соответственно, нам также доступны два способа использования.
Как фоновая картинка
.svg-ei-archive {
background: url(sprites.svg#el-archive) no-repeat 50% 50%;
}
и как обычное изображение
.el-archive {
background: url("data:image/svg+xml;[icon-data]");
}
Однако, на практике, решить эту задачу с наскока не удалось и вопрос требует более детального рассмотрения.
В качестве заключения
Представленные способы не являются единственными для создания SVG-спрайтов. Мне попадались и другие, более экзотические варианты. Какой способ лучше решаться придется вам исходя из того, какой набор иконок имеется и какие возможности для кастомизации вам нужны. На мой взгляд вполне production-ready можно считать режимы css и symbol.