Основы работы с SVG: структура, координаты и примитивы
1. Тег <svg> как корень документа
Каждый SVG-документ начинается с корневого элемента <svg>, который определяет холст для рисования и его параметры.
Основные атрибуты
width и height
Задают физические размеры SVG-области на странице (в пикселях, процентах или других CSS-единицах).
<svg width="300" height="200">
<!-- содержимое -->
</svg>
Если не указать эти атрибуты, SVG займёт 100% ширины контейнера (но высота может быть 0, если не задан viewBox).
viewBox
Самый важный атрибут для адаптивности. Определяет внутреннюю систему координат и пропорции содержимого.
Синтаксис: viewBox="min-x min-y width height"
<svg width="300" height="200" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="coral"/>
</svg>
Что происходит: Круг нарисован в координатах внутреннего пространства 100×100, но растянут на физические 300×200 пикселей. Содержимое масштабируется автоматически.
Практический смысл: Вы можете менять width/height для разных экранов, а viewBox останется неизменным — пропорции сохранятся.
Пример работы с viewBox: ⭐
- БЕЗ атрибута viewBox (Проблема) Браузер сопоставляет координаты 1 к 1. Поскольку контейнер (100px) меньше, чем фигура (200px), мы увидим только левый верхний угол круга. Центр круга (координата 100, 100) окажется в самом углу контейнера.
<!-- Рисунок обрезается -->
<svg width="100" height="100">
<!-- Круг с центром в точке 100,100 и радиусом 100 -->
<circle cx="100" cy="100" r="100" fill="crimson" />
</svg>
Результат: Видна только четверть круга. Остальное скрыто за границами.
- С атрибутом viewBox (Решение) Мы добавляем viewBox="0 0 200 200". Эти цифры сообщают браузеру: «Вся наша графика находится в пространстве от 0 до 200 по осям X и Y. Пожалуйста, сожми это пространство так, чтобы оно целиком поместилось в блок 100×100 пикселей».
<!-- Рисунок масштабируется -->
<svg width="100" height="100" viewBox="0 0 200 200">
<!-- Тот же самый круг -->
<circle cx="100" cy="100" r="100" fill="crimson" />
</svg>
Результат: Круг виден полностью. Браузер автоматически уменьшил изображение (масштаб 1:2), чтобы вся область, заданная в viewBox, поместилась в ширину и высоту svg.
Атрибут preserveAspectRatio
Данный атрибут управляет отображением графики в тех случаях, когда пропорции самого рисунка (заданные в viewBox) не совпадают с размерами контейнера (width и height). Его главная задача — определить, как именно изображение должно масштабироваться и выравниваться, чтобы избежать нежелательного искажения (растягивания или сплющивания).
Синтаксис: preserveAspectRatio="выравнивание режим"
- Выравнивание (Align) Первая часть команды указывает, к какой стороне контейнера следует «прижать» изображение. Она формируется из координат по осям X (горизонталь) и Y (вертикаль):
Min— левый край или верх;Mid— центр;Max— правый край или низ.; Пример: xMidYMid означает выравнивание строго по центру (по обеим осям).
- Режим масштабирования (Meet или Slice)
Вторая часть определяет, как изображение заполняет пространство:
- meet — Вписать полностью. Изображение масштабируется так, чтобы оно было видно целиком. Пропорции сохраняются, но по краям могут остаться пустые области (аналог свойства background-size: contain в CSS).
- slice — Заполнить пространство. Изображение увеличивается, чтобы перекрыть всю доступную область. Пропорции сохраняются, но части рисунка, выходящие за границы, будут обрезаны (аналог свойства background-size: cover в CSS).
Пример: Рассмотрим ситуацию, где квадратное изображение помещается в прямоугольный контейнер
<svg width="200" height="100" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
<rect width="100" height="100" fill="teal"/>
</svg>
Результат:
В данном случае квадрат из viewBox (100×100) помещается в широкий контейнер (200×100). Благодаря значению xMidYMid meet, фигура не растягивается в ширину, а аккуратно масштабируется и размещается ровно по центру холста. Слева и справа от квадрата останется свободное пространство.
2. Координатная система SVG
Начало координат
По умолчанию точка (0, 0) находится в левом верхнем углу холста.
- Ось X: Слева направо (вправо — положительные значения)
- Ось Y: Сверху вниз (вниз — положительные значения) ⚠️
Важно: В отличие от школьной математики, ось Y направлена вниз!
<svg width="200" height="200" viewBox="0 0 200 200">
<!-- Точка (0,0) — левый верхний угол -->
<circle cx="0" cy="0" r="10" fill="red"/>
<!-- Точка (100,100) — центр холста -->
<circle cx="100" cy="100" r="10" fill="blue"/>
<!-- Точка (200,200) — правый нижний угол -->
<circle cx="200" cy="200" r="10" fill="green"/>
</svg>
Единицы измерения
Если единица не указана явно, используются пользовательские единицы из viewBox. Можно использовать:
px(пиксели)em,rem(относительные единицы)%(проценты от размера родителя)cm,mm,in,pt(физические единицы)
<svg width="10cm" height="5cm" viewBox="0 0 100 50">
<rect x="10" y="10" width="30" height="20" fill="purple"/>
</svg>
3. Группировка элементов: тег <g>
Элемент <g> (group) объединяет несколько фигур в логическую группу. Это позволяет:
- Применять общие стили ко всей группе
- Трансформировать элементы вместе (поворот, смещение)
- Структурировать код
Наследование атрибутов
Дочерние элементы наследуют атрибуты группы (если не переопределяют их).
<svg width="200" height="200" viewBox="0 0 200 200">
<g fill="orange" stroke="black" stroke-width="2">
<!-- Оба круга получат оранжевую заливку и черную обводку -->
<circle cx="50" cy="50" r="30"/>
<circle cx="120" cy="50" r="30"/>
</g>
<g fill="none" stroke="blue" stroke-width="3">
<!-- Эти фигуры без заливки, но с синей обводкой -->
<rect x="20" y="100" width="60" height="40"/>
<rect x="100" y="100" width="60" height="40"/>
</g>
</svg>
Трансформации группы
<svg width="200" height="200" viewBox="0 0 200 200">
<g transform="rotate(45 100 100)">
<!-- Вся группа повернута на 45° вокруг точки (100,100) -->
<rect x="80" y="80" width="40" height="40" fill="crimson"/>
<circle cx="100" cy="100" r="5" fill="white"/>
</g>
</svg>
4. Комментарии, метаданные и порядок отрисовки
Комментарии
Используется стандартный XML-синтаксис:
<svg width="100" height="100">
<!-- Это комментарий: он не отображается в браузере -->
<circle cx="50" cy="50" r="40" fill="gold"/>
</svg>
Метаданные
Теги <title> и <desc> улучшают доступность (для скринридеров) и SEO:
<svg width="100" height="100" role="img" aria-labelledby="icon-title">
<title id="icon-title">Иконка домика</title>
<desc>Простая иконка дома с треугольной крышей</desc>
<rect x="20" y="50" width="60" height="40" fill="brown"/>
<polygon points="50,20 10,50 90,50" fill="darkred"/>
</svg>
Порядок отрисовки (z-index)
В SVG нет атрибута z-index. Элементы рисуются в порядке их появления в коде:
- Первый элемент — на заднем плане
- Последний элемент — на переднем плане
<svg width="200" height="100">
<!-- 1. Красный прямоугольник (задний слой) -->
<rect x="20" y="20" width="80" height="60" fill="red"/>
<!-- 2. Синий круг (средний слой) -->
<circle cx="80" cy="50" r="30" fill="blue"/>
<!-- 3. Зелёный квадрат (передний слой) -->
<rect x="100" y="30" width="40" height="40" fill="green"/>
</svg>
Результат: Зелёный квадрат перекрывает синий круг, который перекрывает красный прямоугольник.