Клавиша / esc

shape()

Создаём сложные формы с помощью команд, похожих на SVG, но с поддержкой CSS-единиц измерения.

Время чтения: 7 мин

Кратко

Скопировано

Функция shape() — это новый способ создания сложных форм в CSS. Она похожа на функцию path(), но использует более понятный синтаксис с командами и поддерживает не только пиксели, но и другие CSS-единицы измерения (%, rem, em).

Сравнение shape() и path()

Пример

Скопировано

Создадим треугольник с помощью shape():

        
          
          .triangle {  clip-path: shape(from 50% 0, line to 100% 100%, line to 0 100%, close);}
          .triangle {
  clip-path: shape(from 50% 0, line to 100% 100%, line to 0 100%, close);
}

        
        
          
        
      
Открыть демо в новой вкладке

Как пишется

Скопировано

Функция shape() принимает набор команд, разделённых запятыми. Каждая команда описывает часть пути фигуры.

Начальная точка from

Скопировано

Путь всегда начинается с команды from, которая задаёт начальную позицию:

        
          
          .element {  clip-path: shape(from 0 0, ...);}
          .element {
  clip-path: shape(from 0 0, ...);
}

        
        
          
        
      

Координаты можно указывать в любых CSS-единицах: px, %, em, rem, vw и других.

Все команды shape()

Команда line

Скопировано

Рисует прямую линию от текущей точки до указанной:

        
          
          .element {  clip-path: shape(from 0 0, line to 100% 0, line to 100% 100%, close);}
          .element {
  clip-path: shape(from 0 0, line to 100% 0, line to 100% 100%, close);
}

        
        
          
        
      
Открыть демо в новой вкладке

Команды hline и vline

Скопировано

Упрощённые команды для горизонтальных и вертикальных линий:

  • hline to <x> — горизонтальная линия до указанной координаты X
  • vline to <y> — вертикальная линия до указанной координаты Y
        
          
          .element {  clip-path: shape(    from 0 0,    hline to 100%,    vline to 100%,    hline to 0,    close  );}
          .element {
  clip-path: shape(
    from 0 0,
    hline to 100%,
    vline to 100%,
    hline to 0,
    close
  );
}

        
        
          
        
      
Открыть демо в новой вкладке

Команда curve

Скопировано

Создаёт кривую Безье. Поддерживаются квадратичные и кубические кривые:

        
          
          /* Квадратичная кривая с одной контрольной точкой */.element {  clip-path: shape(    from 0 100%,    curve to 100% 100% with 50% 0,    close  );}/* Кубическая кривая с двумя контрольными точками */.element {  clip-path: shape(    from 0 50%,    curve to 100% 50% with 25% 0 / 75% 100%,    close  );}
          /* Квадратичная кривая с одной контрольной точкой */
.element {
  clip-path: shape(
    from 0 100%,
    curve to 100% 100% with 50% 0,
    close
  );
}

/* Кубическая кривая с двумя контрольными точками */
.element {
  clip-path: shape(
    from 0 50%,
    curve to 100% 50% with 25% 0 / 75% 100%,
    close
  );
}

        
        
          
        
      
Открыть демо в новой вкладке

Команда arc

Скопировано

Рисует дугу эллипса:

        
          
          .element {  clip-path: shape(    from 50% 0,    arc to 50% 100% of 50% 50%,    arc to 50% 0 of 50% 50%,    close  );}
          .element {
  clip-path: shape(
    from 50% 0,
    arc to 50% 100% of 50% 50%,
    arc to 50% 0 of 50% 50%,
    close
  );
}

        
        
          
        
      

Параметры дуги:

  • to <x> <y> — конечная точка дуги
  • of <rx> <ry> — радиусы эллипса по осям X и Y
  • cw / ccw — направление (по часовой / против часовой стрелки)
  • large / small — большая или малая дуга
        
          
          .element {  clip-path: shape(    from 20% 50%,    arc to 80% 50% of 30% cw large,    close  );}
          .element {
  clip-path: shape(
    from 20% 50%,
    arc to 80% 50% of 30% cw large,
    close
  );
}

        
        
          
        
      
Открыть демо в новой вкладке

Команда smooth

Скопировано

Создаёт плавную кривую, автоматически вычисляя контрольные точки на основе предыдущей команды:

        
          
          .element {  clip-path: shape(    from 0 50%,    curve to 33% 50% with 16% 0,    smooth to 66% 50%,    smooth to 100% 50%,    close  );}
          .element {
  clip-path: shape(
    from 0 50%,
    curve to 33% 50% with 16% 0,
    smooth to 66% 50%,
    smooth to 100% 50%,
    close
  );
}

        
        
          
        
      
Открыть демо в новой вкладке

Команда close

Скопировано

Замыкает путь, соединяя текущую точку с начальной:

        
          
          .element {  clip-path: shape(from 0 0, line to 100% 50%, line to 0 100%, close);}
          .element {
  clip-path: shape(from 0 0, line to 100% 50%, line to 0 100%, close);
}

        
        
          
        
      

Относительные координаты с by

Скопировано

Вместо абсолютных координат можно использовать относительные с ключевым словом by:

        
          
          .element {  clip-path: shape(    from 0 0,    line by 100% 0,    /* Сдвиг на 100% вправо */    line by 0 100%,    /* Сдвиг на 100% вниз */    line by -100% 0,   /* Сдвиг на 100% влево */    close  );}
          .element {
  clip-path: shape(
    from 0 0,
    line by 100% 0,    /* Сдвиг на 100% вправо */
    line by 0 100%,    /* Сдвиг на 100% вниз */
    line by -100% 0,   /* Сдвиг на 100% влево */
    close
  );
}

        
        
          
        
      
Открыть демо в новой вкладке

Как понять

Скопировано

Где использовать

Скопировано

Функция shape() работает со следующими свойствами:

  • clip-path — обрезка элемента по форме
  • offset-path — путь для анимации движения
  • shape-outside — обтекание текстом
        
          
          /* Обрезка по форме */.clipped {  clip-path: shape(from 0 0, line to 100% 0, line to 50% 100%, close);}/* Путь для анимации */.animated {  offset-path: shape(from 0 0, curve to 100% 100% with 50% 0);  animation: move 3s infinite;}@keyframes move {  to {    offset-distance: 100%;  }}
          /* Обрезка по форме */
.clipped {
  clip-path: shape(from 0 0, line to 100% 0, line to 50% 100%, close);
}

/* Путь для анимации */
.animated {
  offset-path: shape(from 0 0, curve to 100% 100% with 50% 0);
  animation: move 3s infinite;
}

@keyframes move {
  to {
    offset-distance: 100%;
  }
}

        
        
          
        
      
Открыть демо в новой вкладке

Сравнение с path()

Скопировано

Функция shape() имеет несколько преимуществ перед path():

Особенность path() shape()
Единицы измерения Только пиксели Любые CSS-единицы
Синтаксис SVG-команды (M, L, C...) Понятные слова (move, line, curve...)
Относительные координаты Отдельные команды (m, l, c...) Ключевое слово by
Читаемость Сложнее Проще
        
          
          /* path() — SVG-синтаксис */.element {  clip-path: path("M 0 0 L 100 0 L 100 100 L 0 100 Z");}/* shape() — CSS-синтаксис */.element {  clip-path: shape(from 0 0, line to 100px 0, line to 100px 100px, line to 0 100px, close);}
          /* path() — SVG-синтаксис */
.element {
  clip-path: path("M 0 0 L 100 0 L 100 100 L 0 100 Z");
}

/* shape() — CSS-синтаксис */
.element {
  clip-path: shape(from 0 0, line to 100px 0, line to 100px 100px, line to 0 100px, close);
}

        
        
          
        
      

На практике

Скопировано

Звезда

Скопировано
        
          
          .star {  clip-path: shape(    from 50% 0,    line to 61% 35%,    line to 98% 35%,    line to 68% 57%,    line to 79% 91%,    line to 50% 70%,    line to 21% 91%,    line to 32% 57%,    line to 2% 35%,    line to 39% 35%,    close  );}
          .star {
  clip-path: shape(
    from 50% 0,
    line to 61% 35%,
    line to 98% 35%,
    line to 68% 57%,
    line to 79% 91%,
    line to 50% 70%,
    line to 21% 91%,
    line to 32% 57%,
    line to 2% 35%,
    line to 39% 35%,
    close
  );
}

        
        
          
        
      
Открыть демо в новой вкладке

Сердце

Скопировано
        
          
          .heart {  clip-path: shape(    from 50% 20%,    curve to 90% 45% with 50% 0 / 90% 10%,    curve to 50% 90% with 90% 70% / 60% 90%,    curve to 10% 45% with 40% 90% / 10% 70%,    curve to 50% 20% with 10% 10% / 50% 0,    close  );}
          .heart {
  clip-path: shape(
    from 50% 20%,
    curve to 90% 45% with 50% 0 / 90% 10%,
    curve to 50% 90% with 90% 70% / 60% 90%,
    curve to 10% 45% with 40% 90% / 10% 70%,
    curve to 50% 20% with 10% 10% / 50% 0,
    close
  );
}

        
        
          
        
      
Открыть демо в новой вкладке

Волна

Скопировано
        
          
          .wave {  clip-path: shape(    from 0 60%,    curve to 25% 40% with 10% 60% / 15% 40%,    curve to 50% 60% with 35% 40% / 40% 60%,    curve to 75% 40% with 60% 60% / 65% 40%,    curve to 100% 60% with 85% 40% / 90% 60%,    line to 100% 100%,    line to 0 100%,    close  );}
          .wave {
  clip-path: shape(
    from 0 60%,
    curve to 25% 40% with 10% 60% / 15% 40%,
    curve to 50% 60% with 35% 40% / 40% 60%,
    curve to 75% 40% with 60% 60% / 65% 40%,
    curve to 100% 60% with 85% 40% / 90% 60%,
    line to 100% 100%,
    line to 0 100%,
    close
  );
}

        
        
          
        
      
Открыть демо в новой вкладке

Подсказки

Скопировано

💡 Для сложных форм удобно сначала нарисовать их в графическом редакторе, а затем перевести координаты в команды shape().

💡 Используйте относительные единицы (%) для создания адаптивных форм, которые масштабируются вместе с элементом.

💡 Команда smooth особенно полезна для создания плавных волнистых линий без ручного расчёта контрольных точек.

💡 Свойство не наследуется.

💡 Можно анимировать переходы между формами, если они имеют одинаковое количество команд.

Поддержка в браузерах:
  • Chrome 135, поддерживается
  • Edge 135, поддерживается
  • Firefox, не поддерживается
  • Safari 18.4, поддерживается
О Baseline