W3docs

SVG в HTML5

Все способы встраивания SVG в HTML5 — inline <svg>, <img>, <object>, <embed> и CSS background-image — с анализом компромиссов.

SVG (Scalable Vector Graphics) — это формат на основе XML для описания двухмерной графики в виде фигур — точек, линий, кривых и текста — вместо сетки пикселей. Поскольку браузер отрисовывает SVG из математического описания, изображение остаётся чётким при любом размере и на любом разрешении экрана, поэтому значки, логотипы, диаграммы и схемы так часто поставляются в формате SVG.

HTML5 предоставляет несколько способов разместить SVG на странице, и каждый из них по-своему соотносит доступ к DOM, кэширование, стилизацию и запасной вариант отображения. На этой странице рассматриваются все распространённые методы встраивания и даются рекомендации по выбору между ними.

Если вы только знакомитесь с форматом, начните с введения в SVG. Полный список элементов и атрибутов — в справочнике по SVG.

Встроенный SVG

Самый мощный метод — написать разметку SVG прямо в HTML. Поскольку SVG становится частью документа, каждая фигура является настоящим узлом DOM: её можно стилизовать через CSS, управлять через JavaScript и реагировать на события отдельных путей.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <svg width="300" height="200" viewBox="0 0 300 200"
         xmlns="http://www.w3.org/2000/svg"
         role="img" aria-labelledby="circleTitle">
      <title id="circleTitle">A pink circle outlined in purple</title>
      <circle cx="150" cy="100" r="50" stroke="purple" stroke-width="5" fill="pink" />
    </svg>
  </body>
</html>

Разберём код:

  • Встроенный SVG всегда начинается с тега <svg> и заканчивается </svg>.
  • width и height задают размер SVG-блока на странице (в пикселях CSS).
  • viewBox="0 0 300 200" определяет внутреннюю систему координат: значения — это min-x min-y width height. Браузер масштабирует пользовательские единицы, чтобы они вписывались в указанные width/height, поэтому именно viewBox делает графику по-настоящему масштабируемой и отзывчивой. (Если убрать width/height, SVG растянется по контейнеру, сохранив соотношение сторон viewBox.)
  • xmlns="http://www.w3.org/2000/svg" объявляет пространство имён SVG. Оно обязательно, когда SVG передаётся как отдельный файл .svg; внутри HTML5 браузер обычно определяет его автоматически, но наличие атрибута делает разметку более переносимой.
  • Элемент <circle> рисует круг. cx и cy — координаты x/y его центра (по умолчанию 0,0), r — радиус.
  • stroke и stroke-width управляют обводкой — здесь фиолетовая граница толщиной 5 пикселей. fill задаёт цвет заливки — здесь розовый.

SVG располагает набором базовых элементов-фигур, из которых строится графика. Смотрите список элементов форм SVG ниже.

Опасно

SVG — это XML, поэтому каждый элемент должен быть правильно закрыт. Самозакрывающиеся теги, например <circle ... />, требуют завершающего слеша, а контейнерные теги, например <svg>, — соответствующего </svg>.

Доступность встроенного SVG

Декоративный SVG можно скрыть от вспомогательных технологий с помощью aria-hidden="true". Когда графика несёт смысловую нагрузку, её следует правильно описать:

  • Добавьте role="img", чтобы программы чтения с экрана воспринимали весь <svg> как единое изображение.
  • Добавьте <title> (короткое доступное имя) и при необходимости <desc> (более подробное описание), а затем сошлитесь на них через aria-labelledby.
<svg viewBox="0 0 100 100" role="img" aria-labelledby="t d"
     xmlns="http://www.w3.org/2000/svg">
  <title id="t">Sales chart</title>
  <desc id="d">Bar chart showing a 20% rise in Q4 sales.</desc>
  <rect x="10" y="40" width="20" height="50" fill="teal" />
</svg>

Обратите внимание: <title> и <desc> — это специальные элементы SVG, не являющиеся видимым текстом; <title> в SVG — не то же самое, что HTML-элемент <title> в заголовке документа.

Встраивание внешнего файла .svg

Встроенная разметка раздувает HTML и не может кэшироваться отдельно. Когда есть многократно используемый ресурс, лучше хранить SVG в отдельном файле file.svg и ссылаться на него. Для этого существует четыре распространённых способа.

Как изображение с помощью <img>

Самый простой и широко поддерживаемый подход. SVG ведёт себя как любое другое изображение — кэшируется, поддерживает ленивую загрузку и прост в использовании.

<img src="logo.svg" width="120" height="40" alt="Company logo" />

Компромиссы: вы не можете обращаться к внутренностям SVG из CSS или JavaScript страницы, а скрипты внутри SVG не выполняются. Обычно именно это и нужно для значков и логотипов. Всегда указывайте атрибут alt. Смотрите руководство по HTML <img> и изображениям.

Как объект с помощью <object>

<object> загружает SVG как отдельный документ, поэтому внутренние скрипты выполняются, а обратиться к содержимому можно через contentDocument. Кроме того, между тегами удобно размещать запасное содержимое.

<object type="image/svg+xml" data="diagram.svg" width="300" height="200">
  <img src="diagram.png" alt="Diagram fallback" />
</object>

Компромиссы: взаимодействие скриптов через границу документа регулируется политикой одного источника (CORS), а стилизация SVG из таблицы стилей родительской страницы не применяется. Подробнее — в главе HTML-тег <object>.

Как вставка с помощью <embed>

<embed> также загружает SVG как внешний документ. Этот способ похож на <object>, но не может предоставить запасное содержимое (у него нет закрывающего тега и дочерних узлов).

<embed type="image/svg+xml" src="diagram.svg" width="300" height="200" />

Отдавайте предпочтение <object> вместо <embed>, если нужен запасной вариант. Подробнее — в главе HTML-тег <embed>.

Как CSS background-image

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

<style>
  .hero {
    width: 300px;
    height: 200px;
    background-image: url("pattern.svg");
    background-size: cover;
  }
</style>
<div class="hero"></div>

Можно даже встроить небольшой SVG в виде data URI: background-image: url('data:image/svg+xml,...').

Встроенный SVG против внешнего файла

ВозможностьВстроенный <svg>Внешний (img/object/embed/CSS)
Стилизация фигур через CSS страницыДаНет (только <object>/<embed> через внутренний CSS)
Управление отдельными фигурами из скриптов страницыДаОграничено / заблокировано CORS
Отдельное кэширование от HTMLНетДа
Повторное использование на нескольких страницах без копированияНетДа
Компактный HTMLНетДа

Практическое правило: используйте встроенный SVG, когда нужно анимировать, изменять тему оформления или взаимодействовать с графикой (значки, меняющие цвет при наведении, интерактивные диаграммы). Используйте внешний <img src="*.svg"> для статичных логотипов и декоративных изображений, которые применяются на нескольких страницах сайта.

SVG против растровых изображений

SVG — векторный формат; PNG, JPEG, GIF и WebP — растровые (пиксельные) форматы.

  • Независимость от разрешения. SVG масштабируется до любого размера без размытия и без отдельных файлов @2x/@3x — идеально подходит для значков, логотипов и линейной графики на экранах с высокой плотностью пикселей.
  • Маленький размер для простой графики. Плоские изображения с небольшим числом фигур нередко занимают гораздо меньше места в формате SVG, а текст внутри них остаётся выделяемым и доступным для поиска.
  • Редактируемость и управляемость скриптами. SVG — это текст, поэтому он отображается в системах контроля версий в виде диффов и может быть анимирован.

Когда SVG не подходит: фотографии и детализированные изображения. Описание фотографии в виде тысяч фигур заняло бы огромный объём и медленно отрисовывалось бы — лучше использовать JPEG или WebP. SVG отлично справляется с чёткой геометрией, тогда как сложные попиксельные эффекты лучше подходят для растровых форматов или элемента <canvas>.

Элементы форм SVG

Встроенный SVG предоставляет набор готовых фигур, из которых строится графика:

Смотрите также

Практика

Практика
Какой метод позволяет стилизовать и управлять отдельными фигурами SVG с помощью CSS и JavaScript самой страницы?
Какой метод позволяет стилизовать и управлять отдельными фигурами SVG с помощью CSS и JavaScript самой страницы?
Was this page helpful?