Логотип Workflow

Article

Svg Components Styles

Магия стиля. Обводки, пунктиры и градиенты

В предыдущих уроках мы научились создавать формы и пути. Но пока они выглядят как черно-белые чертежи. В этом шаге мы вдохнем в них жизнь.

SVG обладает уникальной системой стилизации. Она похожа на обычный CSS, но свойства называются иначе. Забудьте про background-color и border — здесь они называются иначе fill (заливка) и stroke (обводка).


1. Атрибуты vs CSS

Стилизовать SVG можно двумя способами.

Способ А: Презентационные атрибуты

Вы пишете стили прямо в теге. Это надежно (работает везде, даже при сохранении картинки на диск), но замусоривает код.

<rect width="100" height="100" fill="red" stroke="black" stroke-width="5" />

Способ Б: CSS (Классы)

Самый профессиональный подход. Вы можете использовать классы, ховеры (:hover) и медиа-запросы.

<style>
  .my-box {
    fill: red;
    stroke: black;
    stroke-width: 5px;
    transition: fill 0.3s;
  }
  .my-box:hover {
    fill: blue; /* SVG поддерживает интерактивность! */
  }
</style>

<rect class="my-box" width="100" height="100" />

Важно: CSS-свойства SVG специфичны.

  • color → не работает (обычно). Используйте fill.
  • border → не работает. Используйте stroke.

2. Глубокое погружение в stroke (Обводка)

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

Концы линий (stroke-linecap)

Определяет, как выглядит начало и конец разомкнутой линии.

  • butt (по умолчанию) — обрубленный край. Линия заканчивается ровно в точке координат.
  • round — скругленный край. Добавляет полукруг после точки координат.
  • square — квадратный выступ. Похож на butt, но продлевает линию на половину её толщины.

Углы (stroke-linejoin)

Определяет, как соединяются две линии на сгибе.

  • miter (по умолчанию) — острый угол.
  • round — скругленный угол (самый приятный для глаз).
  • bevel — срезанный угол (фаска).

Пример:

<svg width="300" height="120" viewBox="0 0 300 120">
  <!-- Butt + Miter (Жесткий стиль) -->
  <polyline points="20,80 50,20 80,80" fill="none"
            stroke="black" stroke-width="15"
            stroke-linecap="butt" stroke-linejoin="miter"/>
</svg>

Вывод:

<svg width="300" height="120" viewBox="0 0 300 120">
  <!-- Round + Round (Мягкий стиль) -->
  <polyline points="120,80 150,20 180,80" fill="none"
            stroke="crimson" stroke-width="15"
            stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Вывод:

<svg width="300" height="120" viewBox="0 0 300 120">
  <!-- Square + Bevel (Технический стиль) -->
  <polyline points="220,80 250,20 280,80" fill="none"
            stroke="steelblue" stroke-width="15"
            stroke-linecap="square" stroke-linejoin="bevel"/>
</svg>

Вывод:


3. Секретная техника: stroke-dasharray

Это свойство создает пунктирную линию. Но именно на нём строится самая популярная SVG-анимация в мире — эффект "саморисующейся" линии.

Как это работает?

stroke-dasharray принимает список чисел: "длина штриха, длина пробела".

  • 5 → штрих 5px, пробел 5px, штрих 5px...
  • 10, 5 → штрих 10px, пробел 5px...

Второе свойство — stroke-dashoffset. Оно сдвигает начало пунктира.

Трюк "Self-drawing line"

Представьте, что у вас есть линия длиной 100 пикселей.

  1. Делаем штрих длиной 100px (вся линия) и пробел длиной 100px.

    stroke-dasharray="100"
    

    Сейчас мы видим сплошную линию.

  2. Делаем сдвиг (offset) на 100px назад.

    stroke-dashoffset="100"
    

    Теперь видимая часть линии (штрих) уехала за пределы видимости, а перед нами — пустой пробел длиной 100px. Линия исчезла!

  3. Если анимировать offset от 100 до 0, линия будет "выезжать" из пустоты.

Демонстрация:

<svg width="300" height="50" viewBox="0 0 300 50">
  <style>
    .draw-me {
      fill: none;
      stroke: darkorange;
      stroke-width: 4;
      /* 1. Задаем пунктир длиной во всю линию (допустим, 280px) */
      stroke-dasharray: 280;
      /* 2. Прячем линию, сдвигая пунктир */
      stroke-dashoffset: 280;
      /* 3. Анимация возвращает offset к 0 */
      animation: draw 2s ease-in-out infinite alternate;
    }

    @keyframes draw {
      to { stroke-dashoffset: 0; }
    }
  </style>

  <line x1="10" y1="25" x2="290" y2="25" class="draw-me"/>
</svg>

Про анимации мы поговорим в главе 7


4. Градиенты: <defs> и <linearGradient>

В отличие от CSS, где градиент — это свойство фона (background: linear-gradient...), в SVG градиент — это отдельный объект.

Он не живет внутри фигуры. Он живет в специальном техническом разделе <defs> (Definitions) и имеет уникальный id. А фигура просто ссылается на него через url(#id).

Линейный градиент

<svg width="200" height="100" viewBox="0 0 200 100">
  <!-- 1. Определяем градиент -->
  <defs>
    <!-- x1,y1 - начало вектора, x2,y2 - конец.
         0% 0% -> 100% 0% означает градиент слева направо -->
    <linearGradient id="myGradient" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" stop-color="gold" />
      <stop offset="100%" stop-color="red" />
    </linearGradient>
  </defs>

  <!-- 2. Используем его -->
  <rect x="10" y="10" width="180" height="80" rx="10"
        fill="url(#myGradient)" />
</svg>

Радиальный градиент

Работает так же, но используем тег <radialGradient> с атрибутами cx, cy (центр) и r (радиус).

<defs>
  <radialGradient id="sunGradient" cx="50%" cy="50%" r="50%">
    <stop offset="20%" stop-color="white" />
    <stop offset="100%" stop-color="orange" />
  </radialGradient>
</defs>
<circle cx="100" cy="50" r="40" fill="url(#sunGradient)" />

Итоговый пример: Неоновая кнопка

Объединим всё: CSS-классы, красивые обводки и градиенты.

<svg width="300" height="100" viewBox="0 0 300 100">
  <defs>
    <linearGradient id="neonGrad" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" stop-color="#00f260" />
      <stop offset="100%" stop-color="#0575E6" />
    </linearGradient>
  </defs>

  <style>
    .btn-rect {
      fill: none;
      stroke: url(#neonGrad);
      stroke-width: 4;
      stroke-linejoin: round;
      /* Пунктирный эффект */
      stroke-dasharray: 200 600;
      stroke-dashoffset: 200;
      transition: all 0.5s;
    }

    .btn-text {
      font-family: Arial, sans-serif;
      font-weight: bold;
      fill: #333;
      transition: fill 0.3s;
    }

    /* Ховер эффект: замыкаем контур и красим текст */
    svg:hover .btn-rect {
      stroke-dasharray: 600 0; /* Делаем линию сплошной */
      stroke-dashoffset: 0;
    }
    svg:hover .btn-text {
      fill: #0575E6;
    }
  </style>

  <g cursor="pointer">
    <!-- Прямоугольник -->
    <rect class="btn-rect" x="50" y="25" width="200" height="50" rx="25" />

    <!-- Текст -->
    <text class="btn-text" x="150" y="55" text-anchor="middle" dominant-baseline="middle">
      HOVER ME
    </text>
  </g>
</svg>
Наведи на меня

Quiz

Проверьте, что вы усвоили

Авторизуйтесь чтоб пройти тесты