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 предоставляет набор готовых фигур, из которых строится графика:
- прямоугольник
<rect>— прямоугольники и прямоугольники со скруглёнными углами - круг
<circle>— окружности, задаваемые центром и радиусом - эллипс
<ellipse>— овалы с независимыми радиусами по x и y - линия
<line>— прямой отрезок между двумя точками - ломаная
<polyline>— последовательность соединённых прямолинейных отрезков - многоугольник
<polygon>— замкнутая фигура из списка точек - путь
<path>— произвольные линии и кривые, наиболее гибкий тип фигуры