Грабли на чистом SVG
В очередной раз встретившись с теми же граблями, я всё-таки решила описать суть проблемы и пути её решения. Речь пойдет о том, как заставить старые браузеры понимать и отображать SVG-элементы — хотя бы пустой блок заданных размеров.
Предположим, вам понадобились SVG-иконки. Вы планируете перекрашивать их по наведению или взаимодействовать с ними как-то ещё, поэтому в качестве способа вставки выбираете не background-image
, а use
.
Подразумевается, что вы подготовили библиотеку иконок и вставили её на страницу.
Для примера возьму такой символ:
Теперь иконку надо вставить в нужное место. Первым делом пишем такое:
Да, я знаю, что в теге нужно указывать пространство имен, чтобы все браузеры правильно понимали тег. Но до сих пор я не сталкивалась с проблемами в отображении такой конструкции, и мне всегда было интересно: а если его не указывать — что и где поломается? Всегда ли мы должны дописывать такой длинный хвост к такому короткому тегу?
viewBox
уже задан в символе, поэтому его не нужно указывать в svg
при вставке на страницу, потребуется задать только размеры иконки.
Задаем размеры:
Конструкция работает во всех браузерах, которые поддерживают SVG.
Теперь нужно позаботиться о старых браузерах и добавить иконке фоновый PNG. Пишем что-нибудь типа:
Обычно фоновая картинка задается только для старых браузеров, например по классу .lt-ie9 SVG
, но здесь я опустила этот момент для простоты.
Что получилось:
See the Pen KnALd by yoksel (@yoksel) on CodePen.
Ссылка на случай, если вы смотрите в IE8, и фрейм не отобразился: codepen.io/yoksel/pen/KnALd
Проверяем в 8-м IE и видим, что ничего не работает, причем сразу по нескольким причинам:
- SVG-элемент не существует с точки зрения IE8. Чтобы браузер начал догадываться о его существовании, нужно в тег
svg
добавить пространство имен, к которому он принадлежит:xmlns="http://www.w3.org/2000/svg"
. - IE8 не понимает обращение к SVG-элементу по тегу — только по классу.
- SVG-элементу обязательно нужно добавить
display: block
илиdisplay: inline-block
.
Исправляем код и получаем вот такое:
Результат:
See the Pen kABcb by yoksel (@yoksel) on CodePen.
Ссылка: codepen.io/yoksel/full/kABcb
SVG-элемент появился в IE8, только вместо векторного содержимого в нем будет фоновая картинка.
Конечно можно не заморачиваться, обернуть SVG в тег span
, например, и задавать фон и размеры ему, но зачем, если можно обойтись без дополнительной разметки?
Вроде бы мы получили в IE8 SVG с фоллбеком, и все работает как надо, но проблемы на этом не заканчиваются. Если на странице есть HTML5-теги, верстка может разъехаться, если у элементов внутри SVG нет закрывающих парных тегов.
Пример такой разметки:
See the Pen irvFb by yoksel (@yoksel) on CodePen.
Ссылка: codepen.io/yoksel/pen/irvFb/
Вот так это демо будет выглядет в 8-м IE:
Html5shiv.js не может корректно отработать, из-за чего HTML5-теги не могут стать блочными.
Решений тут два:
- Добавить в свой CSS явное указание
display: block
для HTML5-тегов. - Закрывать все SVG-теги при вставке на страницу:
Например, есть символ, содержащий path
:
Добавляем закрывающий тег:
Аналогично надо сделать и для всех тегов use
:
Исправленная разметка будет корректно работать во всех браузерах.
Надеюсь, эта статья сэкономит кому-то время в будущем, потому что известные грабли можно обойти не наступая. Да пребудет с вами сила SVG!
- Метки:
- SVG