В очередном проекте мы пробуем встраивать на страницы графику в виде SVG. Заказчик не требует полной поддержки старых браузеров, но ожидает в них доступность основного контента. Для некоторых пиктограмм мы выбрали inline SVG, так как можем легко управлять их внешним видом через стили и даже трансформировать их.
Все изображения собраны в одном SVG-файле shapes.svg
.
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<defs>
<rect id="shape-rectangle" x="1" y="1" width="30" height="30"/>
<circle id="shape-circle" cx="16" cy="16" r="24"/>
</defs>
</svg>
Тут у нас две фигуры: квадрат и круг. Чтобы в дальнейшем мы могли сослаться на них, у каждой фигуры должны быть уникальные значения id
. Забегая вперёд скажу, что их уникальность должна быть не только в пределах SVG, но и в пределах всего документа, где в дальнейшем будет отображаться эта иконка.
На заметку:
Все фигуры определены внутри тега <defs> . Они не будут отображаться, если попытаться открыть этот файл в каком-нибудь редакторе или просмотрщике. На них можно только сослаться. Несколько контуров могут быть объединены в одну фигуру с помощью тега <g>.
Затем в HTML можно сослаться на заготовленные контуры
<svg xmlns="http://www.w3.org/2000/svg"
style="width: 32px; height: 32px;">
<use xlink:href="shapes.svg#shape-rectangle"></use>
</svg>
Браузер отобразит квадрат в блоке размером 32 на 32 пиксела. Габариты блока, разумеется, нужно задавать с помощью CSS. В данном примере я указал их в атрибуте style
только для наглядности.
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="-9 -9 50 50"
style="width: 32px; height: 32px;">
<use xlink:href="shapes.svg#shape-circle"></use>
</svg>
C кругом чуть сложнее так как он не вписывается в желаемые габариты 32 на 32 пиксела. Поэтому inline SVG нужно указать атрибут viewBox. Браузер сам правильно смасштабирует фигуру до размеров блока.
Подводные камни
При использование inline SVG нужно знать и помнить несколько особенностей.
Поддержка
Все современные браузеры прекрасно справляются с базовыми конструкциями SVG. Если вам нужны какие-то особенные фильтры, то стоит протестировать их отдельно.
Internet Explorer
Мы обнаружили, что ссылка на внешний SVG-файл с контурами не работает, если страница отображается в IE. Это известное поведение и исправить хаками его нельзя. Остаётся только явно включить этот SVG в HTML страницу. Соответственно при использовании в
<use xlink:href="#shape-rectangle"></use>
остаётся один якорь (для этого и нужна была уникальность id
).
Если SVG-файл с картинками стал достаточно большим и его уже обременительно каждый раз передавать на странице, то его специально для IE можно загружать динамически и затем уже вставлять на страницу.
<script id="svg-loader">
$.ajax({url: "shapes.svg", cache: true, dataType: "html"})
.done(function (data) {
$("#svg-loader").before(data);
$(".svg-icon > use").attr("xlink:href", function (i, href) {
return href.substr(href.indexOf("#"));
});
});
</script>
Важно, чтобы браузер доставал файл из своего кеша, если это возможно.
Ещё важно, чтобы в SVG разметке не было самозакрывающихся тегов. Нужно явно указывать закрывающий тег, если нет контента. Старые парсеры HTML-супа допускали лишь ограниченное количество самозакрывающихся тегов (
<hr/>
, <br/>
, <input/>
и т.п.) — поэтому мы не можем писать <div/>
. Конструкции SVG могут поломать весь документ при определённом стечении обстоятельств.