Pull to refresh

Используем SVG на сайте

Reading time6 min
Views226K


Оставим за скобками вопрос о целесообразности использования SVG на сайте. Каждый сам для себя должен определить полезность этой технологии. Тем более что эта тема поднималась уже неоднократно.

Сейчас мы рассмотрим методы встраивания SVG, их плюсы и минусы, а так же возможности манипулирования элементами SVG.

Статья рассчитана в первую очередь на тех, кто до сих пор не использует векторную графику на своих сайтах, но очень хочет быть одной ногой в будущем настоящем.
Для любопытных сразу приведу сводную таблицу:
Иконочный шрифт IMG, background-image Object Inline
CSS Манипуляции Частично1 Нет Частично2 Да
JS манипуляции Частично1 Нет Да Да
SVG анимации Нет Да Да Да
Интерактивные SVG анимации Нет Нет Да Да
1 Можно менять цвет, размер, выравнивание и прочее стили обычного текста
2 Стили должны быть прописаны или в самом SVG файле, или подключены внешним стилем в SVG в начале файла:

<?xml-stylesheet type="text/css" href="svgstyle.css"?>

По правде говоря стили прописанные внутри SVG так же будут работать и при использовании тега IMG или background-image, но в этом нет никакого смысла.

Иконочный шрифт



Пример на codepen.io

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

Нужно учесть что при создании собственного шрифта нужно преобразовать все объекты в пути. Тэги и атрибуты которые будут пропущены: circle, rect, stroke, stroke-width, fill, fill-rule.
При использовании иконочного шрифта все элементы SVG объекта объединяются в один символ, и взаимодействовать с ним через CSS и JS можно только как с символом шрифта: менять размер при помощи font-size, менять цвет при помощи color, анимировать при помощи CSS animation или JS и прочее.

Плюсы и минусы такого подхода:
  + иконка ведет себя как символ шрифта, и все параметры настраиваются так же через CSS (размер, цвет, выравнивание и прочее);
  + единственный способ работающий в IE 8 без дополнительных манипуляций;
   все элементы SVG файла объединяются в один символ, поэтому управлять им при помощи CSS или JS можно только как единым целым;
   поддерживаются только одноцветные иконки;
   при сбое загрузки шрифта у пользователя либо не отобразятся иконки совсем, либо, при совпадении кодов иконок с символами юникода, отобразятся соответстующие символы.

SVG как OBJECT



К сожалению (или к счастью) codepen и jsfiddle блокируют загрузку внешних object в целях безопасности.
Встраивание выглядит следующим образом:

<object type="image/svg+xml" data=”your.svg" id=’object’ class=’icon’></object>

Объект встраивает элмемент атрибута data наподобие iframe, добавляя внутрь себя разметку подключаемого файла, поэтому к элементам можно обращаться при помощи JS, но не совсем обычным образом:

var object = document.getElementById("’object’"); //получаем элмент object
var svgDocument = object.contentDocument; //получаем svg элемент внутри object
var svgElement = svgDocument.getElementById("some_id_in_svg"); //получаем любой элемент внутри svg
svgElement.setAttribute("fill", "black"); //меняем атрибуты выбранного элемента

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



Но объект можно трансформировать используя CSS например так:

transform: scale(2, 1);

IE 8 и ниже не поддерживают SVG от слова «совсем» поэтому, если среди пользователей вашего сайта есть эта специфичная аудитория стоит озаботиться проверкой и заменой svg на растровое изображение. Сделать это можно множеством способов, например используя Modernizr добавлять .no-svg класс для body:

if (!Modernizr.svg) {
	$(body).addClass(“no-svg”);
}

.no-svg .icon {
	width: 100px;
	height: 100px;
	background-image: url(“icon.png”);
}

Плюсы и минусы такого подхода:
  + можно использовать внешний CSS файл для управления стилями;
  + поддерживаются SVG анимации и фильтры;
  + поддерживаются интерактивные анимации;
   для IE 8 и ниже необходима замена на растровое изображение.

SVG в IMG или background-image



Пример на codepen.io

Оба способа встраивания чем-то похожи на встраивание при помощи тэга object, например нельзя менять пропорции изменением ширины и высоты контейнера, но имеют больше ограничений.
Подключаемые в SVG внешние стили не будут работать, обратиться к элементам через JS так же не получится. Интерактивные анимации в SVG тоже не сработают. А проблемы с IE 8 и ниже так же остаются.
Но SVG анимации будут работать, в обоих случаях.
В случае с IMG втраивание выглядит как обычная картинка:

<img src="icon.svg">

В случае с background-image как обычный блок:

<div class="icon"></div>

.icon {
	background-image: url("icon.svg");
	width: 90px;
	height: 150px;
}

Так же при помощи background-image можно использовать спрайты, как с png изображениями, а менять размер можно при помощи background-size:

background-size: 90px 150px;

Учитывая что процент людей c экранами device-pixel-ratio которых выше 1 и их устройства не поддерживают svg стремится к нулю(если такие вообще есть), то можно использовать медиа выражения для подключения svg, только для них, а для остальных использовать png версию:

.icon {
	background-image: url("icon.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
	only screen and (min--moz-device-pixel-ratio: 1.5),
	only screen and (-o-device-pixel-ratio: 3/2), 
	only screen and (min-device-pixel-ratio: 1.5) {
	.icon {
		background-image: url("icon.svg");
	}
}

Плюсы и минусы этих подходов:
  + поддерживаются SVG анимации и фильтры;
  + в случае с background-image можно использовать SVG спрайты;
   нельзя менять свойства элементов SVG через CSS или JS;
   не поддерживаются интерактивные анимации;
   для IE 8 и ниже необходима замена на растровое изображение.

Inline SVG



Пример на codepen.io

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

Например имея набор иконок в SVG файле, можно использовать их повторно простой конструкцией вида:

<svg><use x="0" y="0" xlink:href="#some_svg_element_id" /></svg>

где some_svg_element_id id элемента внутри исходного SVG файла.

К отдельно взятому элементу можно, например, применять SVG трансформации:

<svg><use x="0" y="0" xlink:href="#some_svg_element_id" transform="scale(0.5)" /></svg>

Но если внутри исходного SVG к элементу была применена интерактивная анимация, например по клику, как в демо выше, то при дублировании объекта анимация будет срабатывать на всех элементах одновременно.
SVG анимации и фильтры это тема для отдельной статьи, поэтому ограничусь лишь примером SVG фильтра (подробнее о SVG фильтрах), и примером SVG анимации (подробнее о SVG анимациях).
С обесепечением работоспособности для IE 8 и ниже все несколько сложнее, чем в других вариантах. Необходимо добавить дополнительную разметку:

<div class="my-svg-alternate"></div>

if (!Modernizr.svg) {
	$(body).addClass(“no-svg”);
}

.no-svg .my-svg-alternate {
	display: block;
	width: 100px;
	height: 100px;
	background-image: url(image.png);
}

Плюсы и минусы этого подхода:
  + никакой подгрузки внешних файлов;
  + доступны манипуляции с элементами SVG через CSS и JS;
  + поддерживаются SVG анимации и фильтры;
  + поддерживаются интерактивные анимации;
  + возможность повторного использования элементов;
   загрязняется код страницы;
   для IE 8 и ниже необходима дополнительная разметка, и замена на растровое изображение.

Заключение


Каждый из способов хорош по своему, и в зависимости от обстоятельств можно использовать любой из них.
Эта статья в первую очередь мой путь по освоению нюансов SVG, и надеюсь многим она будет так же полезна.
P.S. Всем добра и котиков.
Tags:
Hubs:
Total votes 22: ↑21 and ↓1+20
Comments18

Articles