SVG в HTML: векторная графика
Векторная графика прямо в разметке: иконки, схемы и иллюстрации, которые не пикселят при любом масштабе.
SVG (Scalable Vector Graphics) — это XML-формат векторной графики: вместо пикселей картинка описана фигурами и линиями, поэтому масштабируется без потери чёткости и может жить прямо внутри HTML.
Растровая картинка (PNG, JPEG) — это сетка пикселей: увеличил — и видишь «лесенку». SVG устроен иначе: он хранит инструкции рисования — «нарисуй круг радиусом 40 здесь, проведи линию туда». Браузер каждый раз перерисовывает фигуру под текущий размер, поэтому иконка одинаково резкая и на телефоне, и на 4K-мониторе. А поскольку SVG — это текст-разметка, его можно вставить прямо в страницу и управлять им как обычными элементами.
Зачем это знать на практике
SVG — рабочая лошадка интерфейсов: иконки, логотипы, графики, диаграммы, инфографика. Он весит мало (часто меньше PNG), идеально резок на любом экране, его легко перекрашивать под тему сайта из CSS и оживлять анимацией. Для интерфейсных элементов это почти всегда лучший выбор, чем растровая иконка в трёх плотностях.
Два способа подключить SVG
Первый — как обычную картинку через <img>:
<img src="chart.svg" width="300" alt="График продаж">
Так SVG ведёт себя как чёрный ящик: кешируется как файл, но изнутри его не достать — нельзя перекрасить отдельную фигуру из CSS страницы. Второй способ — inline SVG, когда код фигур лежит прямо в HTML:
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="tomato" />
</svg>
Inline-вариант тяжелее в разметке, зато открыт: каждую фигуру можно стилизовать из CSS, анимировать и менять скриптом. Выбор простой: повторяющиеся иконки и интерактив — inline; крупная статичная иллюстрация, которую не надо трогать — через <img> (она не раздувает HTML и кешируется отдельно).
Базовые фигуры
SVG рисует в системе координат, где начало (0,0) — левый верхний угол, ось Y направлена вниз. Основные примитивы:
<svg width="220" height="80" viewBox="0 0 220 80">
<rect x="10" y="10" width="60" height="60" rx="8" fill="steelblue" />
<circle cx="120" cy="40" r="30" fill="seagreen" />
<line x1="160" y1="10" x2="210" y2="70" stroke="black" stroke-width="3" />
</svg>
<rect> — прямоугольник (rx скругляет углы), <circle> — окружность с центром cx,cy и радиусом r, <line> — отрезок от точки к точке. Есть ещё <ellipse>, <polygon> и <polyline> для ломаных.
path — универсальная фигура
Любую сложную форму рисует <path> через атрибут d — мини-язык команд: M — переместиться (moveto), L — линия (lineto), C — кубическая кривая Безье, Z — замкнуть контур:
<svg width="120" height="120" viewBox="0 0 120 120">
<path d="M60 20 L100 100 L20 100 Z"
fill="gold" stroke="darkorange" stroke-width="2" />
</svg>
Этот d читается так: перейти в точку (60,20) — вершина, провести линию к (100,100), затем к (20,100), замкнуть. Получился треугольник. Иконки из дизайн-инструментов почти всегда экспортируются именно как один-два <path>.
viewBox — сердце масштабирования
Атрибут viewBox="minX minY width height" задаёт внутреннюю систему координат, независимую от реального размера на экране. Это и есть секрет «бесконечной» резкости:
<svg viewBox="0 0 100 100" width="40" height="40">...</svg>
<svg viewBox="0 0 100 100" width="400" height="400">...</svg>
Внутри обоих рисуем в координатах 0–100, а браузер растягивает результат до 40 или 400 пикселей. Можно вообще убрать width/height и задать размер из CSS — фигура подстроится. Без viewBox такого масштабирования не будет, поэтому его ставят почти всегда.
Стилизация через CSS
У inline SVG фигуры красят не только атрибутами, но и из CSS — через свойства fill (заливка), stroke (контур), stroke-width. Это позволяет менять цвет иконки при наведении или под тему сайта без правки самого SVG:
.icon { fill: #555; transition: fill .2s; }
.icon:hover { fill: tomato; }
Особенно удобен ключевое слово currentColor: если у фигуры fill="currentColor", она автоматически принимает цвет текста родителя — иконка «сама» окрашивается в цвет ссылки или кнопки рядом.
Доступность: title и role
Inline SVG для скринридера по умолчанию — пустое место. Если иконка несёт смысл, дайте ей текстовое имя через дочерний <title> и роль:
<svg viewBox="0 0 24 24" role="img" aria-labelledby="t1">
<title id="t1">Открыть настройки</title>
<path d="M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z" />
</svg>
<title> внутри SVG — это не всплывающая подсказка, а доступное имя элемента (его читает скринридер). Связка role="img" + aria-labelledby сообщает вспомогательным технологиям, что перед ними картинка с таким названием. Чисто декоративную иконку, наоборот, прячут атрибутом aria-hidden="true", чтобы не засорять озвучку.
Как это работает под капотом
Inline SVG встраивается прямо в дерево документа наравне с обычными элементами: его узлы — это полноценные DOM-ноды, к ним применяется CSS и к ним можно привязать обработчики событий. Браузер не «вставляет картинку», а рисует фигуры на лету, заново при каждом изменении размера, поэтому масштабирование бесплатно по качеству. SVG, подключённый через <img>, наоборот, изолирован: браузер рендерит его в отдельном контексте, внешний CSS и скрипты внутрь не проникают, зато файл кешируется и не раздувает HTML. Это фундаментальный компромисс: открытость и управляемость против изоляции и кеширования.
Частые ошибки
- Забыть viewBox. Без него SVG не масштабируется корректно: при изменении
widthфигуры обрезаются или не тянутся. - Ждать стилизации от
<img src="icon.svg">. CSS страницы не достаёт внутрь такого SVG — перекрасить фигуру не выйдет, нужен inline. - Путать
<title>SVG с tooltip. Это доступное имя для скринридера, а не подсказка по наведению (для подсказки используютtitle-атрибут или CSS). - Декоративная иконка без aria-hidden. Скринридер пытается её озвучить и сбивает с толку; декор прячут.
- Сырые угловые скобки. Теги SVG в примерах HTML обязательно экранируют (
</>), иначе разметка ломается.
Итоги
- SVG — векторная графика в XML: резкая при любом масштабе, лёгкая, текстовая.
- Через
<img>— изоляция и кеш; inline — доступ из CSS/JS и интерактив. - Базовые фигуры:
<rect>,<circle>,<line>;<path>рисует что угодно командамиM/L/C/Z. viewBoxзадаёт внутреннюю систему координат и даёт «бесконечную» резкость при масштабировании.- Доступность: смысловой иконке —
<title>+role="img"; декоративной —aria-hidden="true".