Содержание
В статье про подготовку графики мы упоминали SVG как формат для векторных элементов и обещали вернуться к нему подробнее. SVG — это полноценная разметка, которую можно встраивать прямо в HTML и стилизовать через CSS. SVG открывает возможности, недоступные растровым форматам: анимацию отдельных элементов, реакцию на hover, эффект рисующейся линии. И всё это без единой строки JavaScript!
Как добавить SVG
Прежде чем анимировать, разберёмся, как SVG попадает на страницу. Способ вставки определяет, что вы сможете с ним делать.
Через тег <img> — самый простой способ. SVG вставляется как обычная картинка: <img src="icon.svg">. Работает, но вы теряете доступ к внутренним элементам. Нельзя менять цвета, анимировать отдельные части, реагировать на :hover. По сути, SVG ведёт себя как статичная PNG картинка, которая просто масштабируемая.
Через CSS background-image аналогично <img>. Удобно для фоновых паттернов и декора, но стилизовать изнутри невозможно.
Inline, прямо в HTML. Вы вставляете код SVG непосредственно в разметку страницы. Это открывает полный доступ к каждому элементу внутри SVG. Можно задавать классы отдельным фигурам, менять их fill и stroke через CSS, анимировать через transition и @keyframes, вешать hover-эффекты. Для веб-плаката это единственный способ, который имеет смысл, когда вам нужна интерактивность.
Как получить SVG-код для inline-вставки? Экспортируйте фигуру из Figma как SVG, откройте файл в текстовом редакторе и вы увидите XML-разметку с тегами <svg>, <path>, <circle>, <rect>. Скопируйте её целиком и вставьте прямо в HTML. Перед вставкой прогоните код через svgomg.net и это уберёт лишние метаданные и сократит размер.
Fill и Stroke
Каждый SVG-элемент имеет два визуальных свойства. fill — это заливка, цвет внутренней области. stroke — это обводка, линия по контуру фигуры. Оба управляются через CSS точно так же, как color или background у обычных HTML элементов.
<svg width="80" height="80" viewBox="0 0 24 24">
<polygon class="star"
points="12,2 15,9 22,9 16,14
18,21 12,17 6,21 8,14 2,9 9,9"/>
</svg>
<svg width="80" height="80" viewBox="0 0 24 24">
<circle class="circle-outline"
cx="12" cy="12" r="10"/>
</svg>
<svg width="80" height="80" viewBox="0 0 24 24">
<rect
class="rect-dual"
x="3"
y="3"
width="18"
height="18"
rx="3"
/>
</svg>
.star {
fill: #FE3904;
stroke: none;
}
.circle-outline {
fill: none;
stroke: #9EFF70;
stroke-width: 3;
}
/* fill — заливка, stroke — обводка.
Это два свойства, которыми вы
будете управлять чаще всего. */
Звёздочка залита красным без обводки. Круг наоборот без заливки, но с зелёной обводкой. Прямоугольник совмещает оба свойства. Этих двух инструментов достаточно для огромного количества визуальных эффектов.
Hover на SVG-элементах
Поскольку inline SVG-элементам можно задавать классы, к ним применяются все те же CSS-псевдоклассы, что и к обычным HTML-элементам. В первую очередь :hover.
<svg width="100" height="100" viewBox="0 0 24 24">
<circle class="hover-circle"
cx="12" cy="12" r="10"/>
</svg>
.hover-circle {
fill: #FE3904;
transition: fill 0.3s ease, transform 0.3s ease;
cursor: pointer;
}
.hover-circle:hover {
fill: #9EFF70;
transform: scale(1.15);
}
/* transition делает смену плавной.
Наведите курсор — круг сменит цвет
и немного увеличится. */
Наведите курсор на каждую фигуру. Круг меняет fill и увеличивается. Прямоугольник получает заливку, которой у него изначально не было. Звёздочка меняет цвет и поворачивается. Всё это — через transition, без JavaScript.
hover можно вешать как на отдельный SVG-элемент, так и на родительский <svg>, чтобы при наведении на всю иконку менялись её внутренние части. Второй подход удобнее, когда нужно координировать несколько изменений одновременно.
<svg class="icon-plus" viewBox="0 0 24 24">
<circle class="bg" cx="12" cy="12" r="11"/>
<path class="cross"
d="M12,6 L12,18 M6,12 L18,12"
fill="none"/>
</svg>
.icon-plus .cross {
stroke: white;
stroke-width: 2;
transition: transform 0.3s ease;
transform-origin: 12px 12px;
}
.icon-plus:hover .cross {
transform: rotate(90deg);
}
/* transform-origin: 12px 12px — центр
SVG-холста (viewBox 0 0 24 24).
Без этого вращение будет
вокруг левого верхнего угла. */
Здесь hover стоит на родительском <svg>. При наведении фон круга меняет цвет, а крестик path поворачивается на 90 градусов, превращаясь из плюса в крестик закрытия. Обратите внимание на transform-origin: 12px 12px — это центр SVG-холста при viewBox 0 0 24 24. Без явного указания transform-origin SVG-элементы вращаются вокруг левого верхнего угла холста, а не вокруг своего центра. Это самая частая ошибка при анимации SVG.
transform-origin в SVG работает иначе, чем в HTML. У HTML элементов по умолчанию точка вращения является центром элемента. У SVG элементов — верхний левый угол SVG-холста 0, 0. Чтобы вращать фигуру вокруг её собственного центра, нужно задать transform-origin явно. Для холста viewBox="0 0 24 24" центр — это 12px 12px, для viewBox="0 0 100 100" — 50px 50px.
Анимации с SVG
hover-эффекты срабатывают при наведении. Если нужна анимация, которая работает постоянно — пульсация, вращение, подпрыгивание — используйте @keyframes, точно так же, как для обычных HTML элементов.
<svg viewBox="0 0 24 24">
<circle class="pulse-circle" cx="12" cy="12" r="10"/>
</svg>
.pulse-circle {
fill: #FE3904;
animation: pulse 2s ease-in-out infinite;
transform-origin: center;
}
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.6; }
}
/* transform-origin: center — обязательно.
Без него SVG-элемент масштабируется
от верхнего левого угла холста. */
Три фигуры, три разных анимации. Круг пульсирует через scale и opacity. Прямоугольник вращается через rotate 360deg. Звёздочка подпрыгивает через translateY. Все три используют transform-origin: center для корректного поведения и infinite для бесконечного цикла.
Для веб-плаката такие анимации полезны для декоративных SVG элементов. Мерцающие звёзды, вращающиеся шестерёнки, пульсирующие точки — всё это создаёт визуальную среду, не требуя взаимодействия со стороны зрителя.
Эффект рисующейся линии
Это, пожалуй, самый эффектный CSS-трюк, доступный только с SVG. Линия как будто рисуется на экране, постепенно проявляясь от начала к концу. Технически за ним стоят два свойства: stroke-dasharray и stroke-dashoffset.
stroke-dasharray превращает сплошную обводку в пунктир и задаёт длину штриха и промежутка. Если задать длину штриха равной длине всего пути, получится один штрих во всю линию и визуально линия выглядит сплошной. stroke-dashoffset сдвигает этот штрих вдоль пути. Если сдвинуть его на всю длину, штрих уедет за пределы видимой области и линия пропадёт. Анимация возвращает offset к нулю, и штрих постепенно въезжает обратно, создавая эффект рисования.
Атрибут pathLength="100" на SVG-элементе упрощает расчёт. Он говорит браузеру: «Считай, что длина этого пути составляет 100 единиц, независимо от реальной длины». После этого stroke-dasharray: 100 и stroke-dashoffset: 100 всегда будут правильными значениями, без необходимости вычислять длину пути через JavaScript.
<svg viewBox="0 0 100 100">
<path class="draw-path"
d="M10,50 Q50,10 90,50 Q50,90 10,50"
pathLength="100"/>
</svg>
<!-- pathLength="100" упрощает расчёт:
длина пути всегда 100 единиц -->
.draw-path {
fill: none;
stroke: #9EFF70;
stroke-width: 2;
stroke-dasharray: 100;
stroke-dashoffset: 100;
animation: draw 3s ease forwards
infinite alternate;
}
@keyframes draw {
to { stroke-dashoffset: 0; }
}
/* stroke-dasharray: 100 — штрих длиной
во всю линию.
stroke-dashoffset: 100 — сдвигаем штрих
так, что линия невидима.
Анимация возвращает offset к 0 —
линия рисуется. */
Фигура в виде знака бесконечности рисуется и стирается в бесконечном цикле. Три CSS-свойства и один @keyframes.
Тот же эффект можно привязать к hover через transition вместо animation.
Наведи курсор в центр
<svg viewBox="0 0 120 60">
<path class="draw-hover-path"
d="M10,50 L30,10 L50,40
L70,15 L90,45 L110,10"
pathLength="100"/>
</svg>
.draw-hover-path {
fill: none;
stroke: #FE3904;
stroke-width: 2;
stroke-dasharray: 100;
stroke-dashoffset: 100;
transition: stroke-dashoffset 1.5s ease;
}
svg:hover .draw-hover-path {
stroke-dashoffset: 0;
}
/* Тот же принцип, но через transition
вместо animation. Линия рисуется
при наведении и стирается
когда курсор уходит. */
Наведите курсор — зигзагообразная линия нарисуется. Уберите курсор — сотрётся обратно. transition на stroke-dashoffset создаёт плавный переход, а длительность 1.5 секунды даёт время насладиться эффектом.
Комбинация приёмов
Самые интересные результаты получаются, когда вы совмещаете несколько SVG-анимаций в одном элементе. Смена fill, рисующаяся обводка и масштабирование могут работать одновременно.
<svg viewBox="0 0 100 100">
<circle class="combo-bg" cx="50" cy="50" r="48"/>
<circle class="combo-ring" cx="50" cy="50" r="45"/>
<polygon class="combo-icon"
points="40,30 40,70 72,50"/>
</svg>
.combo-ring {
fill: none;
stroke: #FE3904;
stroke-width: 2;
stroke-dasharray: 283;
stroke-dashoffset: 283;
transition: stroke-dashoffset 0.8s ease;
}
svg:hover .combo-ring {
stroke-dashoffset: 0;
stroke: #9EFF70;
}
svg:hover .combo-icon {
fill: white;
transform: scale(1.1);
}
/* При наведении: кольцо рисуется,
иконка увеличивается, цвета меняются.
Три перехода работают одновременно. */
Наведите курсор на кнопку воспроизведения. Три вещи происходят одновременно: кольцо «рисуется» по кругу и меняет цвет с красного на зелёный, треугольник-иконка увеличивается и белеет, фон затемняется. Каждый элемент имеет свой transition, и все они срабатывают от одного :hover на родительском <svg>.
Чего SVG не может
SVG не подходит для фотографий. Растровые изображения, фото, скриншоты, сканы, то это точно JPEG, WebP или AVIF. SVG хорош только для графики, которую можно описать кривыми и геометрическими формами.
Сложные SVG из Figma могут быть тяжёлыми. Если иллюстрация содержит сотни path элементов с тысячами точек, SVG-файл может оказаться тяжелее PNG. Прогоняйте такие файлы через svgomg.net и сравнивайте размеры.
Анимация сложных path данных требует JavaScript. CSS позволяет анимировать fill, stroke transform и stroke-dashoffset. Если вам нужно морфить одну форму в другую — менять сам путь d="..." — потребуется JavaScript-библиотека вроде GSAP с плагином MorphSVG.
Хорошее правило: если фигуру можно нарисовать в Illustrator или Figma с помощью Pen Tool, то она подходит для SVG. Если её можно получить только фотографией или сложным растровым рендером, то используйте WebP или AVIF.




