Одним из ограничений в процессе разработки веб-сайтов является присущая им зависимость от прямоугольных элементов. Для придания им более привлекательного визуального эффекта мы используем скругления, искажения и прочие трансформации. Однако при всем этом стоит отметить, что хотя мы и стремимся добиться эстетики, отличной от коробочной, каждый из этих элементов в конечном итоге находится внутри прямоугольной рамки и остальные элементы вокруг располагаются и отрисовываются относительно нее.

К счастью, возможности CSS предоставляют контроль и над этим нативным поведением. Выражены они в спецификации модуля CSS Shapes. Суть ее проста - соседние элементы теперь могут адаптироваться к создаваемым нами пользовательским формам. Иными словами, мы можем указать необходимую форму элемента, после чего контент вокруг будет обтекать этот элемент по ее линии границ.

Крайне важно понимать, что фундаментальная блочная модель остается неизменной, а обтекаемый элемент должен иметь свойство float.

Основные виды форм для плавающих элементов:

  • круглая
  • эллипсообразная
  • многоугольная 
  • на основе формы изображения

Определить форму элемента можно с помощью свойства shape-outside.

.shaped-element {
  shape-outside: <форма элемента>;
}

Круглая форма

Для того чтобы форма плавающего элемента стала кругом, необходимо использовать значение circle(r at cx cy), где r - радиус круга, а cx и cy - координаты центра круга. Если их не указать, в качестве значений по умолчанию будет использоваться центр изображения.

.circle {
  shape-outside: circle(100px at 50% 25%);
  /* текст будет обтекать круг радиусом 100px с центром 50% слева и 25% сверху относительно .circle */
}

Пример того, как можно применить круглую форму:

Эллипсообразная форма

Реализация эллипса очень схожа с кругом, только тут еще учитывается насколько элемент вытянут по горизонтальной или вертикальной оси. Полная запись свойства: shape-outside: ellipse(rx ry at cx cy), где rx и ry - радиусы эллипса, а cx и cy - координаты центра эллипса.

.ellipse {
  shape-outside: ellipse(50px 100px at 50% 50%);
  /* текст будет обтекать эллипс радиусом 50px по горизонтали и 100px по вертикали с центром 50% слева и 50% сверху */
}

Пример того, как можно применить эллипсообразную форму:

Форма на основе изображения

В качестве значения свойства shape-outside может быть адрес картинки. Чтобы обтекаемость текста отработала корректно, картинка должна быть в формате png или svg.

.image {
  shape-outside: url(image.png);
  /* текст будет обтекать контуры загруженной картинки на основе ее альфа-канала */
}

Форма в виде многоугольника

Функция многоугольника представляет из себя набор координат, которые являются вершинами фигуры и последовательно соединены линиями в порядке их обозначения. Свойство имеет следующий вид: shape-outside: polygon(x1 y1, x2 y2, …), где каждая пара x и y как раз и определяет вершины многоугольника. Чтобы использовать форму многоугольника, должно быть указано минимум 3 пары вершин.

.polygon {
  shape-outside: polygon(0% 0%, 100% 0%, 50% 100%);
  /* текст будет обтекать контуры фигуры в форме треугольника */
}

Пример ниже позволяет динамически поиграться с формированием многоугольника и проследить, как его будет обтекать текст: