- PVSM.RU - https://www.pvsm.ru -
Недавно я решал задачу организовать все SVG-файлы, используемые в проекте, в виде одного спрайта. До этого мне приходилось использовать самописное решение для такой задачи. На этот раз я решил воспользоваться популярной библиотекой svg-sprite, однако был сильно удивлен сколько разных способов создания она предлагает. Какой-то единой статьи где были разобраны все способы я не нашел, вся информация была разбросана по блогам и отдельным публикациям. Поэтому я решил собрать доступные в библиотеке способы для генерации спрайтов в одном месте, попутно проанализировав их преимущества и недостатки. Итак, поехали.
Данный режим очень похож на привычный всем способ генерации спрайтов из картинок. Все файлы склеиваются в один, полученный файл ставится в качестве фона блока, а нужная иконка выбирается за счет смещения этого фона.
Пример использования будет выглядеть так
<i class="svg-ei-archive">ei-archive</i>
и соответствующий 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 [1], внутри которого объявляется элементы для дальнейшего использования. Каждому элементу присваивается id, по которому этот элемент будет вызван в теге use [2].
Пример использования
<svg viewBox="0 0 50 50" width="50" height="50">
<use xlink:href="#ei-archive"></use>
</svg>
Для того чтобы use
из примера смог отрендерить элемент, SVG с defs
должен быть также включен в тело документа. Стандартом допускается использовать внешний файлов в xlink:href
, однако это не поддерживается всеми версиями Internet Explorer. К счастью, существует полифил svg4everybody [3], который решает эту проблему.
Преимущества: Метод хорош тем, что предоставляет вам контроль над встраиваемой иконкой через CSS или атрибуты. Вы сможете легко менять ее размеры или цвет.
Недостатки: Скорее всего потребуется некий механизм (макрос, хелпер, функция), который будет генерировать код вставки иконки. При генерации приходится указывать атрибут viewBox
и размеры. Согласно спецификации элементы внутри defs
не должны отображаться, поэтому нельзя будет визуально оценить как выглядят спрайты после оптимизации. Впрочем, svg-sprite
помогает в этом и может создать файл с образцами всех иконок.
В настоящее время использовать этот метод нет смысла, его улучшенной версией является Режим symbol.
Принцип работы этого режима аналогичен предыдущему, но для задания элементов используется тег symbol [4]. Этот элемент, согласно спецификации, может содержать атрибут viewBox
, поэтому отпадает необходимость указывать его при использовании заданного символа. Также элементы, созданные с использованием symbol
, отображаются при рендере, что упрощает визуальный контроль созданных спрайтов. В остальном применение этого метода не отличается от Режима defs.
Пример использования
<svg width="50" height="50">
<use xlink:href="#ei-archive"></use>
</svg>
Преимущества: Аналогично предыдущему режиму (легкая смена цвета и размеров).
Недостатки: Вам также понадобится вспомогательный механизм для вставки иконок. Однако, прочих недостатков метода defs этот режим лишен.
В основе этого метода лежит возможность создания именованных областей просмотра для вашего документа в самом документе. Делается это с помощью тега view [5]. Созданный таким образом спрайт можно использовать двумя способами.
Как обычную фоновую картинку из первого режима
<i class="svg-ei-archive">ei-archive</i>
и как отдельное изображение, встраиваемое с помощью идентификаторов фрагмента (fragment identifiers)
<img src="sprites.svg#ei-archive" width="50" height="50>
На мой взгляд очень удобно. Одна и та же иконка может быть и картинкой, и фоном в зависимости от ситуации. В настоящее время поддержка идентификаторов фрагмента полностью отсутствует в iOS 9.x, несмотря на то, что частичная поддержка была в предыдущей версии.
Преимущества: Можно использовать иконку как для фона, так и для изображения. Легко менять размер, если используется как изображение.
Недостатки: Проблемы с поддержкой в iOS в настоящий момент. Нельзя установить в качестве фона на блок произвольного размера. Нет возможности смены цвета через CSS.
Данный способ также использует именованные области просмотра, однако располагает их одну под другой, подобно слоям в Фотошопе. Каждая область скрыта по умолчанию и становится видна, при ссылке на нее через fragment idetifier
:root>svg {display:none}
:root>svg:target {display:block}
Соответственно, нам также доступны два способа использования.
Как фоновая картинка
.svg-ei-archive {
background: url(sprites.svg#el-archive) no-repeat 50% 50%;
}
и как обычное изображение
<img src="sprites.svg#ei-archive" width="50" height="50>
Ситуация с поддержкой браузерами тут немного хуже, чем в предыдущем способе. Помимо отсутствия поддержки в iOS 9, идентификаторы фрагмента не работают для фоновых изображения в Chrome по 48 версию включительно. Однако в будущем, когда ситуация с поддержкой улучшится, этот способ может стать очень популярным, потому что позволяет использовать одну и ту же иконку как для фона, так и для изображения без ограничений.
Преимущества: Аналогично предыдущему способу, но нет ограничений для изменения размера в зависимости от способа использования.
Недостатки: Проблемы с поддержкой браузерами в настоящий момент. Нет возможности смены цвета через CSS. Из-за особенностей метода все иконки скрыты по умолчанию, поэтому визуально оценить готовый спрайт затруднительно.
Этот метод не является стандартным способом для библиотеки svg-sprite, но может быть создан на ее основе. Смысл его заключается во встраивании самой иконки в файл-стилей через data-url. Библиотека svg-sprite предоставляет широкие возможности для кастомизации шаблонов вывода и дает доступ к исходному коду самой иконки. Поэтому есть возможность создать свой шаблон, который будет генерировать следующий код.
.el-archive {
background: url("data:image/svg+xml;[icon-data]");
}
Однако, на практике, решить эту задачу с наскока не удалось и вопрос требует более детального рассмотрения.
Представленные способы не являются единственными для создания SVG-спрайтов. Мне попадались и другие, более экзотические варианты. Какой способ лучше решаться придется вам исходя из того, какой набор иконок имеется и какие возможности для кастомизации вам нужны. На мой взгляд вполне production-ready можно считать режимы css и symbol.
Автор: fetis26
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/html/111841
Ссылки в тексте:
[1] defs: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs
[2] use: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use
[3] svg4everybody: https://github.com/jonathantneal/svg4everybody
[4] symbol: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol
[5] view: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/view
[6] Источник: https://habrahabr.ru/post/276463/
Нажмите здесь для печати.