Как работает SVG ID?

Я много рассказывал о теге <use> в SVG и использовал его для вывода иконок. Прелесть в том, что с помощью <use> можно ссылаться на часть SVG и выводить только её. Это позволяет использовать схему «много изображений за один запрос, потому что это суперэффективно», которую раньше решали с помощью CSS-спрайтов и иконочных шрифтов.

Перевод статьи «How SVG Fragment Identifiers Work» от Криса Койера.

Но <use> — это инлайновый SVG. Он не поможет, если вы хотите использовать часть SVG в теге <IMG> или в background-image. Вот тут и появляются идентификаторы фрагментов.

Подготовка SVG-спрайта

Один из способов — привести SVG (давайте называть его просто «спрайт») к виду обычного CSS-спрайта.

Мы специально делаем это именно так, чтобы потом быть в состоянии использовать значения viewBox, для вывода отдельных фрагментов, как мы привыкли это делать в обычных спрайтах.

В этом небольшом демо-спрайте используется три иконки. Каждая иконка имеет размер 32×32. Весь спрайт — 32×96. Давайте посмотрим, каким будет viewBox для отдельных частей спрайта:

ViewBox всего спрайта 0 0 32 96
ViewBox первой иконки 0 0 32 32
ViewBox второй иконки 0 32 32 32
ViewBox третьей иконки 0 64 32 32

Атрибуты viewBox указывают на координаты начала слева, координаты начала сверху, ширину и высоту. Обратите внимаение, что каждый раз позиция начала сверху сдвигается на 32. Мы просто показываем другую часть спрайта.

Добавление viewBox в сам SVG

Вы можете указать эти значения viewBox для каждого элемента <view>, внутри SVG.

Теперь мы можем использовать эти части в других местах. Элементы <view> могут быть самостоятельными, как в примере выше, или могут оборачивать другие элементы. В этом случае viewBox отобразится, если совпадает ID.

Демо в спецификации.

Синтаксис в HTML

Применять значения viewBox в SVG-вставленном-как-IMG вы можете следующим образом:

Или, если вы уже настроили view-элементы, то можете ссылаться на них по ID:

Синтаксис в CSS

Вы можете указывать требуемое значение viewBox прямо в пути к изображению в CSS

Или, опять же, ссылаться на них по ID:

Хотя… Если вы используете SVG-спрайт таким образом и у вас пошло что-то не так, то вы можете просто использовать способ из обычных спрайтов:

Я хочу складывать иконки друг на друга

Если у всех иконок одинаковый viewBox и вы хотите просто показывать и скрывать их, когда это необходимо, то это может быть чуть легче.

Поместите их все в одно место (или используйте какой-нибудь сборщик). Вот, я кладу каждую иконку в группу и указывают уникальный ID.

Трюк с отображением нужной иконки заключается в том, чтобы скрыть все иконки и отобразить ту, чей ID совпадает с указанным. Это всё можно сделать на CSS, потому что у нас есть псевдокласс :target.

SVG со всем этим будет выглядеть так:

Поддержка браузеров

Можно посмотреть поддержку в Can I Use, но не всё так просто, потому что некоторые браузеры поддерживают только использование идентификаторов в HTML, а у некоторых какие-то проблемы.

Это моя тестовая страница:

See the Pen SVG Fragment Identifiers in HTML and CSS by Chris Coyier (@chriscoyier) on CodePen.

Вот основные моменты поддержки браузеров, которые я могу отметить:

  • В Firefox всё работает правильно.
  • В IE11 тоже. У IE 9 и 10 небольшие проблемы с background-position, но, в целом, всё неплохо.
  • В последних Chrome/Opera всё работает.
  • Единственное что работает в iOS 8.1 — это ссылка на view внутри img (смотри сноску ниже).
  • Для Android 4.4 подходит только background-position (который вообще не использует идентификаторы). В Android 5 всё нормально.

Комментарий переводчика:

Не знаю где и как проверял автор статьи поддержку в iOS, но, судя по BrowserStack, в iOS9 работает только вывод через background-position. Буду рад, если кто-нибудь потратит пару минут на переход к демке и отпишется как обстоят дела на самом деле.

comments powered by HyperComments

Автор

webbeaver

webbeaver

Верстаю, читаю, учусь