Основы 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.