CSS фигуры позволяют нам создавать более интересные и уникальные макеты страниц, добавляя геометрические элементы, изображения и градиенты, вокруг которых будет размещен текстовый контент. Этот урок научит вас тому, как использовать все это.
До появления CSS Shapes было практически невозможно разработать макет веб-страницы, похожий на страницы журнала, в которой текст был бы расположен свободно. Напротив, в веб-дизайне макеты традиционно создавались с использованием сеток, блоков и прямых линий.
CSS фигуры позволяют создавать геометрические фигуры, вокруг которых может располагаться текст. Этими фигурами могут быть круги, эллипсы, простые или сложные многоугольники, даже изображения и градиенты. Вот несколько примеров практического применения фигур в дизайне: текст может располагаться по кругу вокруг круглого аватара; текст может отображаться поверх простой части фонового изображения в полном размере; текст может «обтекать» буквицы в статье.
Теперь, когда CSS Shapes стали поддерживаться во многих современных браузерах, стоит взглянуть на гибкость и функционал, который они предоставляют. Вы сможете понять, подойдут ли они вам в вашем следующем дизайне или нет.
На момент написания этой статьи CSS фигуры поддерживались в Firefox, Safari, Opera и Chrome, а также в мобильных браузерах (Safari для iOS и Chrome для Android). Фигуры не имеют поддержки в IE, а их использование в Microsoft Edge находится на стадии рассмотрения.
Первый взгляд на CSS фигуры
Сейчас CSS фигуры используются в виде Модуля 1 уровня, который в основном связан со свойством shape-outside
. Оно определяет фигуру, вокруг которой может быть расположен текст.
Учитывая, что существует свойство shape-outside
, вы могли бы подумать, что, соответственно, есть и shape-inside
, благодаря которой текст мог бы находиться в фигуре. В будущем shape-inside
может стать реальностью, но пока это свойство находится в черновиках Модуля 2 уровня CSS фигур. Это свойство не реализуется никакими браузерами.
В этой статье мы рассмотрим, как использовать простейший тип данных <basic-shape>
и устанавливать в нем значения функций фигур. Также вы научитесь устанавливать фигуры с помощью полупрозрачной ссылки или градиента.
Простейшие функции геометрических фигур CSS
В CSS можно определить всевозможные простейшие фигуры. Для этого в свойство shape-outside
вам нужно ввести значения следующих функций:
- circle();
- ellipse();
- inset();
- polygon().
Чтобы применить свойство shape-outside
к элементу, этот элемент должен быть выровнен. Также он должен иметь определенные ширину и высоту. Давайте пробежимся по 4 простейших геометрическим фигурам и разберемся, как их можно использовать.
Круг
Начнем с функции circle()
. Представьте себе следующую ситуацию: у нас есть круглый аватар автора, который выровнен по левому краю, и мы хотим, чтобы текст авторского описания огибал эту окружность. Чтобы текст стал круглой фигурой, будет недостаточно применить border-radius: 50%
к элементу аватара. В таком случае для текста аватар все еще будет прямоугольным.
С помощью фигуры круга мы можем показать, как текст будет огибать окружность.
Начнем с создания класса circle
в обычном div
. Сделаем пару параграфов. (Я использовал цитаты Боба Росса в качестве замещающего текста.)
<div class="circle"></div>
<p>Example text...</p>
В классе circle
делаем так, чтобы элемент был выровнен по левому краю. Устанавливаем для него равные высоту (height) и ширину (width). Применяем shape-outside
к circle()
.
.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
}
Если мы просмотрим страницу, то выглядеть она будет так:
Как вы можете заметить, текст огибает фигуру, но мы ее не видим. Если вы наведете на элемент курсор в используя инструменты «Developer Tools», вам будет показана сама фигура.
Вы можете предположить, что можно установить цвет фона (background) или добавить в элемент изображение, и тогда фигура появится. Давайте попробуем:
.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
background: linear-gradient(to top right, #FDB171, #FD987D);
}
К сожалению, при установке фонового цвета для круга получается прямоугольник. Именно этого мы и пытались избежать:
Мы видим, что текст огибает фигуру, но сам элемент не имеет формы. Если мы хотим отображать функции фигур, придется использовать свойство clip-path
. Оно принимает много значений, сходных с shape-outside
. Мы можем присвоить этому свойству ту же функцию circle()
.
.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
clip-path: circle();
background: linear-gradient(to top right, #FDB171, #FD987D);
}
В течение всей оставшейся статьи я буду использовать clip-path, что поможет нам определить фигуры.
Функция circle()
получает опциональный параметр - радиус. В нашем случае по умолчанию радиус (r) равен 50% или 100px. Если использовать circle(50%)
или circle(100px)
, то получится тот же результат, который мы уже видели. Вы могли заметить, что текст расположен вплотную к фигуре. Можно использовать свойство shape-margin
, чтобы установить границы для фигуры. Они могут быть в px, % или em. Можно использовать любую другую стандартную единицу измерения для CSS.
.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle(25%);
shape-margin: 1rem;
clip-path: circle(25%);
background: linear-gradient(to top right, #FDB171, #FD987D);
}
Вот пример круга с радиусом 25% и примененным свойством shape-margin
:
Помимо радиуса в функцию фигуры можно добавлять расположение при помощи at
. По умолчанию расположение - центр окружности. Это значит, что круг будет написан так: circle(50% at 50% 50%)
или circle(100px at 100px 100px)
. Два этих значения - горизонтальное и вертикальное расположение соответственно.
Чтобы вам было понятнее, как работает расположение, можно присвоить горизонтальному расположению значение 0, чтобы сделать идеальный полукруг.
circle(50% at 0 50%);
Система установки координат также известна как «коробка ссылок».
Позднее мы узнаем, как использовать изображение вместо фигуры или градиента. А теперь перейдем к следующей функции фигуры.
Эллипс
На функцию circle()
похожа ellipse()
, которая создает овал. Чтобы продемонстрировать ее работу, можем создать элемент и с классом ellipse:
<div class="ellipse"></div>
<p>Example text...</p>
.ellipse {
float: left;
shape-outside: ellipse();
clip-path: ellipse();
width: 150px;
height: 300px;
background: linear-gradient(to top right, #F17BB7, #AD84E3);
}
Теперь мы устанавливаем разные значения высоты и ширины, чтобы получить вертикально вытянутый овал.
Разница между circle()
и ellipse()
состоит в том, что эллипс имеет два радиуса - rx и ry, или же радиус по оси x и радиус по оси y. Значит, представленный выше пример можно также записать так:
ellipse(75px 150px);
Параметры расположения для кругов и эллипсов одинаковы. Радиус - это не только единица измерения. Он также может включать опции farthest-side
и closest-side
.
closest-side
относится к длине от центра до ближайшей стороны «коробки ссылок». А farthest-side
, наоборот, относится к расстоянию от центра до наиболее удаленной стороны «коробки ссылок». Это значит, что данные два значения никак не влияют на расположение, если не установлена позиция не по умолчанию.
Ниже продемонстрирована разница при повороте с использованием farthest-side
и closest-side
для эллипса с 25% смещением от осей X и Y.
ellipse(farthest-side closest-side at 25% 25%)
ellipse(farthest-side closest-side at 25% 25%)
Вставка
Пока что мы имели дело только с круглыми фигурами. Однако можно вставлять и прямоугольники с помощью функции inset()
.
<div class="inset"></div>
<p>Example text...</p>
.inset {
float: left;
shape-outside: inset(75px);
clip-path: inset(75px);
width: 300px;
height: 300px;
background: linear-gradient(#58C2ED, #1B85DC);
}
В этом примере мы создадим прямоугольник 300px на 300px, который смещен на 75px для всех сторон. Тогда мы получим фигуру 150px на 150px и 75px пространства вокруг нее.
Мы можем увидеть, что прямоугольник вставлен в поле, которое игнорируется текстом.
Фигура inset()
может иметь свойство border-radius
с параметром round. В этом случае текст будет скруглять края. Ниже показан пример с 25px на всех сторонах и скруглением 75px.
inset(25px round 75px)
Как и в случае с сокращениями padding и margin, inset будет принимать значения top right bottom left в порядке по часовой стрелке (inset(25px 25px 25px 25px)
). Если вы примените только одно значение, то оно будет принято для всех сторон (inset(25px)
).
Многоугольник
Самой интересной и гибкой из функций фигур является polygon()
. Она может принимать массив точек x и y и создавать фигуру любой сложности. Каждый элемент массива подразумевает xiyi. Функция будет записываться так:
polygon(x1 y1, x2 y2, x3 y3...)
Наименьшее количество наборов точек, которое мы можем добавить к многоугольнику, - 3. Тогда вы получите треугольник.
<div class="polygon"></div>
<p>Example text...</p>
.polygon {
float: left;
shape-outside: polygon(0 0, 0 300px, 200px 300px);
clip-path: polygon(0 0, 0 300px, 200px 300px);
height: 300px;
width: 300px;
background: linear-gradient(to top right, #86F7CC, #67D7F5);
}
В этой фигуре первая точка имеет координаты (0,0). Эта точка находится в верхнем левом углу для div. Вторая точка - 0 300px. Это нижняя левая точка в div. Третья и последняя точка - 200px 300px. Она находится на ⅔ оси X и все еще располагается на нижней границе. В результате получается такая фигура:
Интересное использование фигуры многоугольника заключается в том, чтобы сделать так, чтобы текст располагался между двумя или более многоугольниками. Раз уж фигура polygon()
так гибка и динамична, это одна из наиболее крупных возможностей создавать уникальные макеты, напоминающие развороты в журналах. В данном примере мы поместим текст между двумя полигональными фигурами.
<div class="left"></div>
<div class="right"></div>
<p>Example text...</p>
.left {
float: left;
shape-outside: polygon(0 0, 0 300px, 200px 300px);
clip-path: polygon(0 0, 0 300px, 200px 300px);
background: linear-gradient(to top right, #67D7F5, #86F7CC);
height: 300px;
width: 300px;
}
.right {
float: right;
shape-outside: polygon(200px 300px, 300px 300px, 300px 0, 0 0);
clip-path: polygon(200px 300px, 300px 300px, 300px 0, 0 0);
background: linear-gradient(to bottom left, #67D7F5, #86F7CC);
height: 300px;
width: 300px;
}
Очевидно, создавать сложные фигуры самостоятельно и вручную - очень сложно. К счастью, существует несколько инструментов, которые помогают создавать многоугольники. В Firefox есть встроенный редактор фигур. Его можно использовать, если кликнуть по полигональной фигуре в inspector.
Пока что в Chrome есть несколько расширений, которые можно использовать: например, CSS Shapes Editor.
Многоугольники можно применять для того, чтобы вырезать фигуры вокруг изображений или других элементов. В другом примере мы можем создать буквицу, нарисовав многоугольник вокруг большой буквы.
<div class="letter">R</div>
<p>Example text...</p>
.letter {
float: left;
font-size: 400px;
font-family: Georgia;
line-height: .8;
margin-top: 20px;
margin-right: 20px;
shape-outside: polygon(5px 14px, 233px 20px, 246px 133px, 189px 167px, 308px 304px, 0px 306px) content-box;
clip-path: polygon(5px 14px, 233px 20px, 246px 133px, 189px 167px, 308px 304px, 0px 306px);
}
Ссылки
Интересная возможность в CSS фигурах состоит в том, что вам необязательно всегда открыто описывать фигуру при помощи соответствующей функции. Вы также можете использовать ссылку или полупрозрачное изображение для определения фигуры. Текст автоматически окружит ее.
Важно заметить, что используемое изображение должно быть совместимо с CORS, иначе вы получите ошибку, как ниже:
Access to image at 'file:///users/tania/star.png' from origin 'null'
has been blocked by CORS policy: The response is invalid.
Вы точно не получите такую ошибку, если будете использовать изображение с одного и того же сервера.
В отличие от других примеров, вместо div мы будем использовать тег img. В этот раз с CSS все очень просто: поместите url()
в свойство shape-outside
, как и в случае с background-image
.
<img src="./star.png" class="star">
<p>Example text...</p>
.star {
float: left;
height: 350px;
width: 350px;
shape-outside: url('./star.png')
}
Так как я использовал изображение звезды с прозрачным фоном, текст знал, какие области являются прозрачными, а какие - нет, и был размещен в соответствии с этим.
Градиенты
Наконец, в качестве фигуры также можно применять градиенты. Это то же самое, что изображения. Как и в примере с изображением, который был показан выше, текст будет знать, что в прозрачных частях нужно будет огибать фигуру.
С градиентами мы будем использовать новое свойство - shape-image-threshold
. Оно определяет границу в фигуре или соотношение прозрачных и непрозрачных частей.
Я сделаю пример градиента с 50%/50% распределением между цветом и прозрачностью. Я установлю значение .5 для shape-image-threshold. Это значит, что все пиксели, непрозрачность которых больше 50%, должны считаться частью изображения.
<div class="gradient"></div>
<p>Example text...</p>
.gradient {
float: left;
height: 300px;
width: 100%;
background: linear-gradient(to bottom right, #86F7CC, transparent);
shape-outside: linear-gradient(to bottom right, #86F7CC, transparent);
shape-image-threshold: .5;
}
Мы можем видеть, что градиент в центре идеально разделен пополам между цветной и прозрачной частями.
Заключение
В этой статье мы узнали о 3 свойствах CSS фигур: shape-outside
, shape-image-threshold
и shape-margin
. Мы также научились использовать значения функций для создания кругов, эллипсов, вставных прямоугольников и сложных многоугольников, причем текст может огибать все эти фигуры. Также нами было продемонстрировано, как фигуры могут определять прозрачные части изображений или градиентов.