Основы SVG

Что это такое

SVG — язык разметки для двумерной векторной графики: внутри системы координат документ объявляет фигуры — пути, прямоугольники, круги, линии, — а браузер отрисовывает их как часть DOM страницы. Разметка, а не картинка, поэтому элемент SVG можно выбирать через CSS, он реагирует на события и создаётся сценарием, как любой другой узел.

Почему это важно

У растрового изображения разрешение фиксировано: при масштабировании оно размывается, а цвет текста страницы принять не может. У SVG обеих проблем нет — он не зависит от разрешения, а встроенный в разметку наследует currentColor, так что одна и та же иконка годится для любой темы. К тому же для линейной графики он намного меньше: иконка или логотип часто занимают несколько сотен байт данных пути вместо десятков килобайт пикселей. Основы стоит выучить, а не просто скачивать файлы, потому что именно система координат и правила стилизации решают, можно ли перекрасить данную иконку, надёжно задать её размер и сделать доступной.

Ключевые идеи

Атрибут viewBox задаёт систему координат

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

<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
  <path d="M4 12h16M12 4v16" fill="none" stroke="currentColor" stroke-width="2" />
</svg>

Без viewBox рисунок привязан к собственному размеру и не масштабируется вместе с элементом.

Фигуры и пути — весь словарь

Обойтись можно семью элементами: rect, circle, ellipse, line, polyline, polygon и path, а произвольный контур описывает путь с командами M, L, C и Z. Почти каждый файл иконки, который вам встретится, состоит из одного пути: именно так инструмент дизайна экспортирует фигуру.

Заливка, обводка и currentColor

fill закрашивает внутреннюю область, stroke — контур, и оба принимают currentColor, а он разрешается в CSS-свойство color элемента. Благодаря этому один файл иконки обслуживает и тёмную, и светлую тему без дублирования.

.icon {
  width: 1.25em;
  height: 1.25em;
  color: var(--icon-colour, currentColor);
}

.icon path { fill: currentColor; }

Задавая размер в em, вы привязываете иконку к размеру шрифта рядом — как правило, встроенной иконке это и нужно.

Текст не масштабируется как фигуры

Всё, что пользователь должен прочесть, оставляйте HTML-текстом рядом с иконкой, а не текстом SVG и не контуром пути. Нарисованные буквы нельзя перевести или найти поиском, и их размер не меняется через настройки шрифта читателя.

Встроенный SVG — поддерево DOM

После встраивания элементы SVG можно выбирать и анимировать, но его id глобальны для документа: две копии одной иконки дадут одинаковые id, если не ограничить их областью видимости. Именно поэтому иконки обычно генерируют как компоненты, а не вставляют разметку как есть.

Практика

Нарисуйте иконку, которую можно перекрасить

Соберите иконку размером 24 на 24 из простых фигур и возьмите currentColor для заливки и обводки. Разместите на странице две копии с разными цветами текста и разными размерами.

Готово, когда: обе копии берут цвет родителя, хотя CSS ни на SVG не нацелен, и обе масштабируются без размытия.

Исправьте ошибку масштабирования

Возьмите SVG, который отказывается масштабироваться, уберите жёстко заданные width и height и задайте viewBox по границам рисунка.

Готово, когда: если задать родителю width в em, отрисованный размер плавно меняется, а пропорции сохраняются.

Частые ошибки

  • Отсутствие viewBox — графика не масштабируется, а размывается или обрезается; исправить: объявите координатное пространство, в котором нарисованы пути.
  • Непоследовательное использование fill и stroke в наборе — иконки выглядят так, будто пришли из разных семейств; исправить: выберите одно соглашение и применяйте его к каждой иконке.
  • Жёстко заданный цвет — иконка не подчиняется теме и в тёмной теме выделяется; исправить: используйте currentColor и задавайте color в CSS.
  • Текст, нарисованный путями — его нельзя перевести, найти поиском или изменить размер; исправить: используйте настоящий текст рядом с иконкой.
  • Две вставки одного inline-SVG с id внутри — одинаковые id делают ссылки неоднозначными; исправить: сделайте иконку компонентом и ограничьте область id или уберите их.

Что читать дальше

  • Язык гипертекстовой разметки (HTML) (02-frontend/03-html) — SVG это разметка, поэтому те же правила элементов, атрибутов и дерева применимы.
  • Системы иконок и доступность (02-frontend/17-svg-icon-systems/02-icon-systems-and-accessibility) — как упаковать эту графику и подписать её.
  • Каскадные таблицы стилей (CSS) (02-frontend/05-css) — как стилизуется и измеряется отрисованный SVG.