Svg спрайты что это
Символьный SVG-спрайт. Подробное руководство
Если вы из тех разработчиков, кто только задумывается о внедрении в свой проект svg-спрайтов или из тех, кто давно хотел, но не знает с чего начать, эта статья определенно будет вам полезна. Об удобстве и пользе спрайтов вообще и SVG-спрайтов в частности немало информации как на родном, так и на иностранном языке. Поэтому, в этой статье, мы не будем останавливаться на вопросах целесообразности их использования, а перейдем непосредственно к сути.
SVG-спрайты бывают разные. Самый простой вариант – это склеивание всех иконок в один файл и последующее использование его в виде фоновой картинки со смещением background-position для каждой иконки. Все, кто работал ранее с растровыми спрайтами, знакомы с такой технологией и найдут ее для себя простой и понятной. К сожалению, в таком варианте спрайта масштабирование и управление цветом будет недоступно, также, как и возможность использовать спрайт в теге img.
Другие виды svg-спрайтов выглядят интереснее. Об их разновидностях, преимуществах и недостатках хорошо изложено в этой статье на Хабре. Там же рассказывается о библиотеке svg-sprite, к которой мы позднее вернемся.
Сегодня, мы рассмотрим генерацию и использование спрайтов, на примере символьного SVG-спрайта. Выбор в его пользу был сделан не случайно, это именно тот вариант спрайта, который имеет на сегодняшний день наилучшую поддержку браузерами, а также позволяет свободно управлять размером и цветом иконки.
Устройство спрайта
Использование на странице
Чтобы иметь возможность использовать иконки из символьного svg-спрайта, в первую очередь, нужно добавить этот спрайт на страницу. Берем спрайт, полученный нами в предыдущем разделе, и вставляем на страницу.
После того, как спрайт находится на странице, вывести нужную иконку можно с помощью тэга use :
Управление с помощью CSS
Если вы не хотите, чтобы иконки по умолчанию были черными, можно сделать отдельный файл стилей, содержащий дефолтные настройки для каждой иконки. Это хороший способ сэкономить немного времени и стилизовать только отдельные иконки по мере необходимости.
Обращаясь к классу элемента svg, с помощью CSS можно указать нужный размер, изменить цвет, назначить эффект наведения, добавить анимацию, применить svg-фильтры.
Список свойств, доступных для изменения через CSS, есть на сайте W3C
Стилизация отдельных частей иконки
При непосредственном встраивании svg-картинки на страницу, мы можем управлять различными частями изображения, обращаясь к назначенных им классам. Возникает резонный вопрос, можно ли такой же фокус провернуть с svg-спрайтом? Ответ — нет.
Но кое-что сделать все же можно.
Есть два способа, которыми можно добиться желаемого. И один из них даже имеет неплохую поддержку современными браузерами.
Это ключевое слово, содержащее значение свойства color. currentColor можно использовать в любых свойствах, принимающих значение color
То есть, если у нас есть элемент, в котором один и тот же цвет используется сразу в нескольких свойствах, достаточно указать его только один раз, а дальнейшее упоминание доверить ключевому слову currentColor :
Есть и второй способ, гораздо более гибкий. В дело вступают CSS-переменные и здесь уже нет ограничений по количеству стилизуемых элементов. А принцип остается тот же: ко всем элементам, которые вы планируете изменять средствами CSS, добавляем нужные вам атрибуты.
В качестве значений указываем CSS-переменные, через которые и проводим стилизацию в CSS:
Конечно, настолько подробную стилизацию вряд ли удобно производить подобным способом. В таких случаях, думаю удобнее обходиться без спрайта вообще, но всегда полезно иметь представление о доступных возможностях.
С поддержкой CSS-переменных дела обстоят немного хуже, в случае некоторых версий IE, Opera Mini и Android Browser, она отсутствует вовсе.
Вообще о стилизации svg элементов через use есть замечательная статья на английском, в которой очень подробно и с примерами изложена эта тема.
Использование внешней ссылки на спрайт
Давайте представим, что вы дошли до текущего раздела и все у вас прекрасно работает. Не радует только необходимость держать спрайт в теле страницы. На самом деле, ничего плохого в этом нет.
Если вас все устраивает, можно продолжать в том же духе.
При таком способе подключения есть только один существенный недостаток – отсутствие кэширования спрайта. К счастью, эта проблема легко решаема. Внутри атрибута xlink:href достаточно прибавить к идентификатору путь, по которому расположен ваш спрайт:
Этот скрипт добавляет поддержку ссылок на внешние svg-файлы не только в IE, но и в любых других браузерах, не поддерживающих подобный функционал.
Однако, несмотря на такую радужную картинку с подключением внешнего svg-спрайта, не спешите убирать его со страницы. Сейчас узнаете почему.
«Я все сделал как в статье, а у меня не работает»
Очень распространенная ситуация, когда все вроде бы правильно, но не работает. Причин может быть множество и не всегда можно сразу увидеть, что не так. Начать нужно с проверки примеров, приведенных выше. Вставляете себе на страницу спрайт и выводите точно, как в примере, любую иконку. Если с этим проблем не возникло, следовательно что-то не так с вашим спрайтом.
Что же может не работать? Давайте рассмотрим несколько примеров.
Иконка не отображается совсем или отображается частично
Попробуйте добавить в ваш спрайт одну из иконок, приведенных в примерах выше. Если она выводится без проблем, скорее всего проблема в ваших иконках. В этом случае, первое, что нужно сделать – это взять отдельную иконку и проверить в браузере. Если с отображением вне спрайта проблем нет, значит следует получше к ней присмотреться.
Внимательный осмотр может показать, что возможно часть элементов иконки или вся она использует в качестве фона градиент. И это тот самый момент, когда можно подкатывать глаза и начинать страдать.
Практически во всех статьях про SVG вообще и спрайты в частности (эта не исключение), в качестве примеров используются простые и красивые иконки с хорошо читаемой разметкой. В жизни же все далеко не так прекрасно и в качестве исходного материала для спрайта, вы вполне можете встретить, например, такое:
Это действительно поможет Firefox и не навредит остальным браузерам, но только лишь в том счастливом случае, если ваш спрайт присутствует на странице. Если же, вы используете внешнюю ссылку на спрайт, то после вышеуказанных манипуляций, вместо градиента иконка в IE (версия 11) приобретет сплошной черный цвет.
Далее, Chrome (версия 55) также, при использовании внешней ссылки на спрайт, проигнорирует градиент. И здесь тот же фокус, что и с Firefox уже не действует. Внятных объяснений такому поведению в хроме я не нашла. Если сталкивались с подобной проблемой и нашли решение, делитесь в комментариях.
Не получается изменить цвет иконки
Использование в качестве background-image
Я думаю, ни один верстальщик не любит лишней HTML-разметки. Инлайновый SVG это конечно хорошо и замечательно, но далеко не всегда удобно. Как же быть со старым добрым background-image? Думаю, правильным ответом на этот вопрос, будет «это невозможно». Но оказывается, все же возможно. Хотя придется, конечно, потрудиться.
Известно, что в качестве фона можно указывать внешний svg-файл. Поскольку код внутри symbol не отображается на странице, понадобиться комбинация из тегов view и use для каждой иконки.
То есть для каждой иконки, которую вы хотите использовать в качестве инлайнового svg и в качестве фона, нужно будет добавить вот такой код:
Как видите, технология пока сыровата, и полной поддержки браузерами не наблюдается. Сложно сказать, приживется ли она в будущем, но знать о такой возможности всегда полезно.
Автоматическая генерация спрайта
Если вы как и я, не любитель собирать спрайты вручную, можно автоматизировать этот процесс с помощью плагина gulp-svg-sprite. Плагин имеет множество опций и умеет не только символьные спрайты но и многие другие.
npm install gulp-svg-sprite
Редактируем gulpfile.js и создаем объект конфигурации, который в дальнейшем будем передавать плагину:
Свойство shape отвечает за настройки генерируемых svg-фигур. Здесь можно настраивать максимальные размеры, отступы, влиять на идентификаторы, которые генерируются автоматически и еще много чего.
Создаем таск для спрайтов
Заключение
SVG-спрайты – прекрасная альтернатива растровым спрайтам и иконочным шрифтам. Даже не смотря на имеющиеся ограничения и небольшие проблемы, это определенно перспективная технология, которая улучшается с каждым днем. Не поленитесь потратить немного времени на ее изучение. В этой статье, я постаралась максимально подробно собрать и рассмотреть возможные проблемы при использовании символьных svg-спрайтов, а также способы их решения. Надеюсь, мой опыт будет вам полезен.
Автор svg-иконок из примеров — Elias Bikbulatov
Создание SVG sprite с помощью gulp
Для начала необходимо, что-бы был установлен gulp (если он не установлен, то устанавливаем с помощью npm install gulp)
Далее в файле gulpfile.js создаем task в котором делаем необходимые настройки модуля, про которые можно прочесть перейдя по ссылке www.npmjs.com/package/svg-sprite
модуль имеет множество настроек и несколько разных модов
В данном случае нас интересует создание спрайта, который можно использовать как в HTML, так и с помощью фоновой картинки в CSS
для этого нам потребуется mode: stack
добавляем код в файл gulpfile.js
Чтобы запустить созданную задачу необходимо в консоле прописать gulp svgSprite
если задача успешно отработала, то увидим сообщение в консоле Finished ‘svgSprite’ after 884 ms
И теперь можно проверять наличие созданного файла с названием, которое мы задали в настройках, в данном случае sprite.svg
он должен находиться по указанному нами пути app/design/frontend/Magento/vendor/web/images/
В спрайт добавляются все иконки находящиеся в каталоге, который мы указали в настройках, в данном случае app/design/frontend/Magento/vendor/web/sprite/*.svg
и каждой иконке присваивается id который соответствует имени файла (id так же можно менять в настройках, это описано в документации)
Чтобы обратиться к нужной иконке из спрайта необходимо к имени файла sprite.svg дописать id иконки, например sprite.svg#shopping-cart
Теперь можно использовать наш спрайт, это можно делать как с помощью HTML так и с помощью CSS, используя background
мы можем менять ширину и высоту иконок с помощью селекторов CSS width и height
если мы добавим спрайт в HTML с помощью svg, то можем менять и цвет иконок с помощью селектора CSS fill
Используем SVG на сайте
Оставим за скобками вопрос о целесообразности использования SVG на сайте. Каждый сам для себя должен определить полезность этой технологии. Тем более что эта тема поднималась уже неоднократно.
Сейчас мы рассмотрим методы встраивания SVG, их плюсы и минусы, а так же возможности манипулирования элементами SVG.
Статья рассчитана в первую очередь на тех, кто до сих пор не использует векторную графику на своих сайтах, но очень хочет быть одной ногой в будущем настоящем.
Для любопытных сразу приведу сводную таблицу:
Иконочный шрифт | IMG, background-image | Object | Inline | |
---|---|---|---|---|
CSS Манипуляции | Частично 1 | Нет | Частично 2 | Да |
JS манипуляции | Частично 1 | Нет | Да | Да |
SVG анимации | Нет | Да | Да | Да |
Интерактивные SVG анимации | Нет | Нет | Да | Да |
1 Можно менять цвет, размер, выравнивание и прочее стили обычного текста
2 Стили должны быть прописаны или в самом SVG файле, или подключены внешним стилем в SVG в начале файла:
По правде говоря стили прописанные внутри SVG так же будут работать и при использовании тега IMG или background-image, но в этом нет никакого смысла.
Иконочный шрифт
Плюсы и минусы такого подхода:
+ иконка ведет себя как символ шрифта, и все параметры настраиваются так же через CSS (размер, цвет, выравнивание и прочее);
+ единственный способ работающий в IE 8 без дополнительных манипуляций;
– все элементы SVG файла объединяются в один символ, поэтому управлять им при помощи CSS или JS можно только как единым целым;
– поддерживаются только одноцветные иконки;
– при сбое загрузки шрифта у пользователя либо не отобразятся иконки совсем, либо, при совпадении кодов иконок с символами юникода, отобразятся соответстующие символы.
SVG как OBJECT
К сожалению (или к счастью) codepen и jsfiddle блокируют загрузку внешних object в целях безопасности.
Встраивание выглядит следующим образом:
Объект встраивает элмемент атрибута data наподобие iframe, добавляя внутрь себя разметку подключаемого файла, поэтому к элементам можно обращаться при помощи JS, но не совсем обычным образом:
Стоит отметить что в CSS стили для SVG элементов отличаются от стандартных, полный список стилей поддерживаемых SVG можно посмотреть тут.
SVG ведет себя не как обычное изображение, его нельзя непропорционально трансформировать, задавая ширину и высоту. Объект внутри будет занимать максимальную площадь и центрироваться в контейнере:
Но объект можно трансформировать используя CSS например так:
Плюсы и минусы такого подхода:
+ можно использовать внешний CSS файл для управления стилями;
+ поддерживаются SVG анимации и фильтры;
+ поддерживаются интерактивные анимации;
– для IE 8 и ниже необходима замена на растровое изображение.
SVG в IMG или background-image
Оба способа встраивания чем-то похожи на встраивание при помощи тэга object, например нельзя менять пропорции изменением ширины и высоты контейнера, но имеют больше ограничений.
Подключаемые в SVG внешние стили не будут работать, обратиться к элементам через JS так же не получится. Интерактивные анимации в SVG тоже не сработают. А проблемы с IE 8 и ниже так же остаются.
Но SVG анимации будут работать, в обоих случаях.
В случае с IMG втраивание выглядит как обычная картинка:
В случае с background-image как обычный блок:
Так же при помощи background-image можно использовать спрайты, как с png изображениями, а менять размер можно при помощи background-size:
Учитывая что процент людей c экранами device-pixel-ratio которых выше 1 и их устройства не поддерживают svg стремится к нулю(если такие вообще есть), то можно использовать медиа выражения для подключения svg, только для них, а для остальных использовать png версию:
Плюсы и минусы этих подходов:
+ поддерживаются SVG анимации и фильтры;
+ в случае с background-image можно использовать SVG спрайты;
– нельзя менять свойства элементов SVG через CSS или JS;
– не поддерживаются интерактивные анимации;
– для IE 8 и ниже необходима замена на растровое изображение.
Inline SVG
В этом варианте SVG код, получить который можно открыв любой SVG файл текстовым документом, встраивается непосредственно в код страницы.
Несомненно такая конструкция ухудшает читаемость кода, и увеличивает его объем, но открываются новые возможности.
Например имея набор иконок в SVG файле, можно использовать их повторно простой конструкцией вида:
где some_svg_element_id id элемента внутри исходного SVG файла.
К отдельно взятому элементу можно, например, применять SVG трансформации:
Но если внутри исходного SVG к элементу была применена интерактивная анимация, например по клику, как в демо выше, то при дублировании объекта анимация будет срабатывать на всех элементах одновременно.
SVG анимации и фильтры это тема для отдельной статьи, поэтому ограничусь лишь примером SVG фильтра (подробнее о SVG фильтрах), и примером SVG анимации (подробнее о SVG анимациях).
С обесепечением работоспособности для IE 8 и ниже все несколько сложнее, чем в других вариантах. Необходимо добавить дополнительную разметку:
Плюсы и минусы этого подхода:
+ никакой подгрузки внешних файлов;
+ доступны манипуляции с элементами SVG через CSS и JS;
+ поддерживаются SVG анимации и фильтры;
+ поддерживаются интерактивные анимации;
+ возможность повторного использования элементов;
– загрязняется код страницы;
– для IE 8 и ниже необходима дополнительная разметка, и замена на растровое изображение.
Система иконок с SVG-спрайтами
Я всегда был приверженцем шрифтов иконок. Многим сайтам действительно необходима система упорядочивания иконок, и шрифты иконок предлагают для этого отличную возможность.
И даже если в IE версии 9 и выше нормально заработают встроенные SVG и элементы для ссылок, использование иконок остается более прогрессивной практикой.
Прежде всего, давайте рассмотрим, как это работает.
Это одна из самых крутых вещей в работе с SVG — они сами являются исходными файлами.
Вы можете через Illustrator (или другую программу) сохранить их как угодно со всеми сопутствующими элементами:
Если захотите, вы можете сделать это вручную. Я так и сделал. Вам даже не нужно просматривать конечный файл. Просто назовите его svg-defs.svg или как-то в этом роде.
В этом файле должен быть только тег с тегом (который просто означает, что вы определяете элементы для последующего использования), а затем связка тэгов (группа).
Каждый тег будет иметь уникальный идентификатор, и включать полный маршрут к файлу, а также содержать еще много дополнительных данных для каждой иконки:
С помощью данной команды вы можете установить Grunt :
Проверьте, доступны ли в нем все задачи:
А затем задайте конфигурацию:
Подключение SVG в верхней части документа
Или любым другим способом по вашему усмотрению.
Использование иконок в любом месте
Теперь вы можете использовать иконки везде(!), где вам нравится:
Убедитесь, что вы используете соответствующие имена классов SVG для задания размеров:
Ура: вы можете задавать их стили (и стили их частей) с помощью CSS
Одна из причин, по которым мне очень нравятся шрифты иконок, это то, что вы можете оформлять их с помощью CSS.
Эта техника одного окна, которая позволяет нам делать, все что нужно, и даже больше этого:
Другой способ: IcoMoon
После выбора необходимых шрифтов просто нажмите кнопку SVG внизу окна приложения, и на выходе вы получите набор элементов, в том числе демо-страницу, созданную с помощью встроенного SVG-метода :
Поддержка браузерами
Что касается поддержки браузерами, то здесь зоной риска являются IE версии 8 и ниже, Safari 5 и ниже, IOS 4.3 и ниже и Android 2.3 и ниже.
Но если вы ориентируетесь на пользователей « двух последних основных версий »- то, как правило, в подавляющем большинстве браузеров SVG поддерживаются.
Следует помнить, что иконки можно использовать в качестве вспомогательного элемента. В этом случае поддержка браузерами не имеет критического значения.
Если это будет отдельный основной элемент, без которого содержимое сайта не может отображаться, это может стать проблемой.
Я мог бы еще много рассказать о поддержке браузерами шрифтов иконок. Однако просто убедитесь, что вы применяете их правильно.
Делать следующим образом будет намного правильнее
В идеале у нас должно быть что-то наподобие следующего:
Это действительно работает в некоторых браузерах, то есть вы могли бы и не включать их в верхней части документа.
Это означает, что будет отправляться дополнительный HTTP-запрос, но тогда вы можете более эффективно использовать кэширование (не раздувать кэш документа).
При тестировании Джонатан Нил обнаружил, что для нормальной работы в тег необходимо включать xmlns-атрибут :
Джонатан Нил установил и этот факт :
Его демо-версия теперь содержит также метод, который формирует Ajax-запрос к содержимому и включает этот блок, который позволяет обрабатывать заливки и в IE 9. Не так эффективно, скорее как полизаливки.
Браузеры воспринимают как своего рода DOM :
Теперь, мы можем определять, скажем, конкретный
Но это будет влиять на все объекты этого пути. Вы могли бы придумать что-то на манер:
Но в одних браузерах он не поддерживается, в других не понятно, как будет работать, и будет ли работать вообще.
«Минусы» шрифтов иконок
Векторная основа : ничья
Сбои в работе : На первый взгляд SVG кажется простым в работе (если поддерживается браузером).
Однако иногда с ними происходят странные вещи. Например, если вы используете карту символов, как с обычными буквами, то при загрузке шрифтов может произойти сбой, и вы получите при выводе большое количество случайных символов.
Или применяете карту « Для области частного использования », и некоторые браузеры могут повторно привязать их к действительно специфическим символам, таким как розы, однако при повторной привязке могут возникнуть сложности с воспроизведением оригинальной структуры.
Но установки Nginx могут подхватить их неправильно. К сожалению.
Применимость : Может быть, кто-нибудь подскажет мне? Можем ли мы / могли бы мы придать элементу атрибут заголовка или что-то в этом роде?
, который был бы визуально спрятан?
Как мы используем SVG-спрайты
При верстке макета из PSD часто иконки вставлены в формате SVG, а если нет — просим их у дизайнера. Ранее мы использовали иконочные шрифты, но недавно увидели преимущества спрайтов и решили попробовать с ними поиграться внедрить их в процесс разработки. Нам нравятся иконочные шрифты, но они имеют ряд недостатков(на эту тему почитайте CSSTricks). Эксперимент удался, и вот как мы организовали систему.
Условия
Что нам нужно от спрайтов:
Поехали
Устанавливаем плагины(мы это делаем глобально и потом линкуем):
В gulpfile объявляем плагины:
Варим спрайт
Давайте разберемся, что тут происходит по частям.
Удаляем атрибуты style и fill из иконок, для того чтобы они не перебивали стили, заданные через css.
Теперь сделаем из получившегося спрайт и положим в папку:
Щепотка стилей
Сделаем для создания scss отдельный таск.
В свойстве cssFile объявляем, куда положить на scss файл(потом инклудим его).
В свойстве templates объявляем, где взять для него шаблон. Код шаблона:
Получаем _svg_sprite.scss следующего содержания:
Скомпилированный css будет таким:
Обратите внимание, что размеры иконок выражены через em, что позволит нам в дальнейшем управлять ими через font-size.
Составляем итоговый таск, и запускаем его:
Подключаем на страницу
Итак мы получили html-файл с иконками и scss-файл с оформлением. Далее подключим файл на страницу, используя кеширование через localStorage. Этот процесс подробно описан в статье Caching SVG Sprite in localStorage.
Подключаем js-файл следующего содержания:
Файл подключен, после первой загрузки он кешируется. Если вам нужно нужно обновить спрайт в js-файле приведенном выше меняйте параметр revision на +1. Иконки вставляем через миксин jade, т.к. это быстро и удобно:
Теперь, чтобы встроить иконку вызываем миксин с её именем:
Открываем страницу в браузере:
Пока размеры иконок в натуральную величину и имеют стандартный цвет. Изменим это(не в сгенерированном файле, а в главном):
Результат:
Вот и все, мы получили рабочую систему подключения иконок через спрайты, но есть еще один момент.