Статьи

CSS Shapes: ломая прямоугольные дизайнерские кандалы

Возможности HTML5 и CSS3 полностью затмевают то, что мы могли сделать в Интернете всего пять лет назад. Спецификация уровня 1 модуля CSS Shapes может вырвать нас из прямоугольных ограничений сети и превратить веб-дизайн в новые высоты. Он позволяет стилизовать элементы в различных формах (например, в кружочках или в форме пятиугольников), а текст обтекать элементы гораздо более естественными способами (оборачивать текст по краям соблазнительного дизайна, а не придерживаться квадратных границ) , В этой статье мы расскажем о возможностях CSS Shapes с помощью нескольких небольших демонстраций, чтобы показать, что возможно, и помочь вам начать исследовать!

О спецификациях фигур

Данная спецификация является рекомендацией кандидата, которая является «явным призывом к тем, кто находится за пределами соответствующих рабочих групп или самому W3C, для реализации и технической обратной связи».

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

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

Что вам нужно для экспериментов с CSS-фигурами

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

Если вы используете Chrome (не Canary), вставьте его в адресную строку:

chrome://flags/#enable-experimental-web-platform-features 

Затем нажмите «Включить» в разделе «Включить экспериментальные функции веб-платформы» и выберите «Перезапустить сейчас», чтобы перезапустить браузер и дать ему новые сверхспособности CSS.

Не обращая внимания на эти введения, давайте разберемся, что же может предложить спецификация Shapes.

Собственность shape-outside

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

Во время моих демонстраций я буду приводить несколько фрагментов из книги «География детских сказок» или веселое путешествие по Европе Ф. Уинслоу. Британский музей был настолько любезен, что выпустил несколько произведений в общественное достояние, и эта детская книга оказалась одной из них (а также в ней было несколько изображений разного размера!).

Наш первый и очень простой пример выглядит так:

До закругленных углов

HTML выглядит так:

 <h1>Laplanders</h1> <img src="http://www.patrickcatanzariti.com/experiments/css3/cssshapes/lapland.png" class="lapland" /> <p>They can bend bows most easily that the most powerful Swedes or Norwegians could not bend at all. They dress,as you see, altogether in skins or coarse wool. The women dress very like the men, turning their hair up in a funny kind of knot.</p> 

Мы добавим свойство shape-outside в CSS элемента image ( .lapland ):

 .lapland { float: left; shape-outside: inset(1% round 45%); } 

В результате углы изображения становятся хорошо округленными, чтобы соответствовать естественному радиусу границы иллюстрации:

После закругленных углов

А для тех, кто просматривает в поддерживающем браузере, вот демонстрация CodePen:

Мы более подробно рассмотрим этот пример и параметры функции inset в следующем разделе.

Какие виды фигур возможны?

Свойство shape-outside позволяет нам использовать несколько различных функций для определения формы:

inset()

Функция inset() позволяет вам определить внутренний прямоугольник в области с плавающей точкой. Это было бы полезно, если у вас есть дизайн, где вы хотите, чтобы текст перекрывал часть прямоугольного изображения. Может быть, у вас есть небольшая цветовая окраска вокруг изображения, в которое вы не возражаете, если текст перемещается, или вокруг изображения много белого пространства, которое вы хотели бы сохранить в некоторых случаях, но хотите стиль в других. Функция inset сделает все это возможным!

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

 shape-outside: inset(10px, 5px, 10px, 5px); 

Вы можете сократить значение так же, как в значениях полей / отступов, поэтому следующее дает прямоугольник вставки, который составляет 1% от всех ребер элемента:

 shape-outside: inset(1%); 

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

Если вы добавите «round», а затем укажете размер с помощью обычного синтаксиса border-radius , появятся вышеупомянутые возможности округленных контейнеров. Это то, что мы сделали в нашем примере с Laplander выше.

Я приведу несколько вариантов, чтобы объяснить наш предыдущий пример немного подробнее. Приведенный ниже код дает элементу радиус border-radius 10px, который вставляется от края нашего изображения на 1%:

 shape-outside: inset(1% round 10px); 

Наш пример выше следует этой схеме, но радиус намного округлен, чтобы соответствовать нашему изображению:

 shape-outside: inset(1% round 45%); 

Вы можете пойти дальше с этими настройками, задав для каждого угла разный border-radius . Следующее, например, дало бы верхний левый 5px, верхний правый 10px, нижний правый 5px и нижний левый 5px:

 shape-outside: inset(1% round 5px 10px 5px 5px); 

circle()

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

 shape-outside: circle(); 

Чтобы продемонстрировать, как это работает, допустим, у нас было следующее:

Перед кругом

Добавив приведенный выше код к изображению в правом верхнем углу приведенного выше снимка экрана, мы получим следующее:

После круга

Пример CodePen:

Установка радиуса круга

Вы можете установить радиус круга в первом аргументе функции circle() .

По умолчанию радиус круга равен половине ширины элемента:

 shape-outside: circle(50%); 

Вы можете установить радиус в 25%, чтобы круговая область с плавающей запятой равнялась четверти ширины элемента:

 shape-outside: circle(25%); 

Примечание. Проценты в circle() вычисляются по формуле с использованием ширины и высоты в тех случаях, когда элемент не является идеальным квадратом. (Спасибо Razvan Caliman в комментариях за указание на это)

Есть два других способа установить радиус окружности, которые являются более новыми понятиями, но довольно аккуратными: closest-side и farthest-side определяют, как браузер должен определять радиус нашего круга, используя границы самого элемента. Они не будут иметь значения, если наш элемент квадратный, только в тех случаях, когда у вас есть прямоугольный элемент.

closest-side вычисляет радиус круга от краев элемента, ближайшего к центру. Это значение по умолчанию, поэтому использование circle() само по себе эквивалентно circle(closest-side) . Если у нас есть прямоугольный элемент, и мы используем следующее:

 shape-outside: circle(closest-side); 

closest-side гарантирует, что круг плотно прилегает к контейнеру, как показано на рисунке ниже (я добавил оранжевую рамку по краю изображения, чтобы вы могли видеть, где находятся границы):

После круга ближайшей стороны

Смотрите это на CodePen:

farthest-side , с другой стороны, вычисляет радиус круга от краев, наиболее удаленных от центра. Это обрежет круг на одной паре ребер. Если у нас есть новый прямоугольный элемент, подобный представленному выше, но с обрезанным круговым изображением, мы можем использовать farthest-side :

 shape-outside: circle(farthest-side); 

Это позволит нам обернуть текст в такие элементы:

После дальнего круга круга

Смотрите это на CodePen:

Перемещение центра круга

Вы можете использовать ключевое слово at чтобы переместить центр круга. Вы можете сделать это в тех случаях, когда круг не находится точно в центре изображения, или в случаях, когда вы хотите получить полукруг от одного края. Например, если мы используем этот CSS на высоком изображении:

 shape-outside: circle(farthest-side at left); 

Мы можем получить круг, центр которого находится слева от изображения и высота которого соответствует высоте элемента:

Полукруг поплавок

На CodePen:

Вы можете использовать кучу разных значений позиционирования для центра круга. Теоретически, все, что позволяет синтаксис позиции CSS :

 shape-outside: circle(closest-side at center); shape-outside: circle(closest-side at 10% 10%); shape-outside: circle(closest-side at center); 

Вы даже можете получить довольно конкретные, указав радиус круга и положение. Например, приведенный ниже CSS создаст круг, равный половине ширины элемента, центр которого находится слева от элемента (0) и на 25% сверху:

 shape-outside: circle(25% at 0 25%); 

ellipse()

Если вместо этого у вас есть овальная форма, а не круг, вы можете использовать функцию ellipse . При этом высота и ширина эллипса будут высотой и шириной вашего изображения, если вы не определите радиус, аналогичный тому, как вы определяете его для круга — просто с двумя значениями, одно для радиуса х и одно для радиуса у.

Следующий код:

 shape-outside: ellipse(); 

Результаты в этом:

Базовый эллипс

На CodePen:

Установка размера эллипса

Мы можем создать овал другого размера так же, как и при определении радиуса круга, просто с двумя значениями: одно для ширины, а второе для высоты:

 shape-outside: ellipse(25% 10%); 

Вероятно, есть лучший пример из реальной жизни, но это дает представление о том, как это будет выглядеть. У меня есть изображение с меньшим овалом внутри в размере, определенном выше (я снова добавил оранжевую рамку, чтобы показать, где находится изображение):

Маленький эллипс

Смотрите это на CodePen:

Вы также можете определить ширину и высоту с помощью значений closest-side и farthest-side как мы делали с кругом, только с эллипсом мы снова используем два значения: одно для ширины и одно для высоты:

 shape-outside: ellipse(closest-side closest-side); 

Перемещение центра эллипса

Вы можете перемещать центр эллипса тем же методом, что и элемент circle :

 shape-outside: ellipse(25% 10% at 0 25%); 

polygon()

Функция polygon() позволяет вам определять любое количество точек для вашей фигуры, позволяя обтекать ваш текст даже самым неловким изображением!

Вы определяете полигоны, устанавливая координаты для каждой точки. Координаты могут быть в пикселях или в процентах. Первый пункт должен быть в состоянии связать с последним:

 shape-outside: polygon(x1 y1, x2 y2, x3 y3, x4 y4, x5 y5); 

Возьмите этот пример с очень причудливой иллюстрацией, обозначающей букву «D» в начале нашей страницы:

Причудливый образ D без новой упаковки

Затем мы можем определить область с плавающей точкой многоугольника следующим образом:

 shape-outside: polygon(88% 0, 90% 15%, 83% 22%, 93% 31%, 100% 36%, 72% 73%, 35% 75%, 19% 100%, 0 100%, 0 0); 

Это отрегулирует область с плавающей точкой так, чтобы наш текст обернулся вокруг определенного полигона, который мы определили:

Необычное изображение D завернутый

На CodePen:

Но … Работать с координатами многоугольника сложно!

Я согласен. Трудно работать, когда дело доходит до сложных изображений, особенно при использовании процентов! Здесь есть расширение Brackets, которое поможет вам.

Если вы не хотите использовать скобки, есть простой онлайн-инструмент для разработки многоугольника, который вы хотели бы использовать.

Обязательно попробуйте, если вам нужен более быстрый способ определения координат многоугольника. Или вы можете настроить многоугольники, используя сами изображения, о которых я расскажу позже!

Формы из изображений

Одна из очень удобных функций CSS Shapes заключается в том, что если у вас есть прозрачное изображение в формате PNG или GIF, вы можете использовать альфа-канал для определения области плавания. Это так же просто, как эти две строки:

 shape-outside: url(b.png); shape-image-threshold: 0.0; 

Формат URL аналогичен формату, используемому для ссылки на background-image и может быть либо тем же изображением, что и элемент, либо совершенно другим. Вы можете создавать новые изображения, единственной целью которых является определение альфа-канала для фигуры, если вы того пожелаете. Это немного проще, чем полигоны, но добавит дополнительный HTTP-запрос.

shape-image-threshold определяет уровень непрозрачности, который вы хотите получить. 0.0 полностью прозрачен, а 1.0 полностью непрозрачен.

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

Наше изображение с прозрачностью

Пример кода сверху приведёт к следующему:

Полигон по изображению

А вот демоверсия CodePen:

Обновление редактора. Как мы уже обсуждали в комментариях, демонстрация CodePen выше при тестировании в Chrome Canary с включенным надлежащим флагом, похоже, не работает должным образом из-за перекрестной ошибки в Chrome или CodePen. Это будет работать, если вы обновите страницу несколько раз, но сейчас вы можете обратиться к демонстрационной версии Патрика для рабочей версии.

Один важный момент — если вы загружаете HTML из вашей файловой системы (например, file:///Users/philkensebben/Web/yourfile.html ), а не с веб-сервера, вы file:///Users/philkensebben/Web/yourfile.html с ошибкой совместного использования ресурсов из разных источников, подобной этой :

 Image from origin 'file://' has been blocked from loading by Cross-Origin Resource Sharing policy: Received an invalid response. Origin 'null' is therefore not allowed access. 

Поэтому обязательно проверьте это на удаленном веб-сервере, чтобы избежать путаницы по поводу того, почему он не работает!

Формы из коробки Модель

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

Вы можете использовать различные области для блочных моделей в качестве области плавания. Я добавил изображение ниже, чтобы напомнить вам о различных частях блочной модели в CSS:

Пример коробочной модели

  • Синяя область — поле для margin-box . Это составлено из поля элемента и находится за границей элемента.
  • Черная область — это border-box . В приведенном выше примере у нас есть граница 2px.
  • Оранжевая область — это padding-box . Это область, которая окружает ваш контент (например, наше изображение).
  • Само изображение находится в окне content-box . Это область коробки, которая содержит наше изображение.

Вы можете использовать эти граничные области в качестве плавающей области следующим образом:

 shape-outside: margin-box; shape-outside: border-box; shape-outside: padding-box; shape-outside: content-box; 

В основном, какой бы вы ни указали, будет место, куда будет переноситься текст. Если вы определите shape-outside как margin-box , то текст будет перенесен на край поля (например, синяя область в приведенном выше примере). Если вы определите его как border-box , он будет перенесен на край вашей рамки и так далее.

Одним из простых способов использования этого является придание округлым углам области плавания вашего изображения (как мы это сделали со inset но немного проще в реализации и обслуживании). Этот CSS добавит разрыв между нашим изображением и текстом в 5 пикселей, а также обернет текст вокруг изображения значением border-radius в 150 пикселей:

 border-radius: 150px; margin: 5px; shape-outside: margin-box; 

Который выглядит так:

Пример использования margin-box и border-radius

И на CodePen:

Тот же эффект с border-radius можно сделать с помощью border-box , padding-box и content-box — он просто меняет, насколько близко текст попадает на изображение.

Свойство shape-margin

У вас также есть возможность добавить пространство вокруг заданной плавающей области CSS Shape, чтобы текст не попал на края ваших изображений. Это удобно в тех случаях, когда вы не используете значения блочной модели для своей фигуры.

В спецификации сказано, что вы можете использовать либо длину (например, px, em. Rem и т. Д.), Проценты или значение функции calc() . Только Chrome Canary в настоящее время поддерживает проценты, но стабильная версия Chrome поддерживает функции length и calc() (если эти функции calc() не включают проценты). Вот несколько примеров:

 shape-margin: 10px; shape-margin: 1em; shape-margin: 5%; shape-margin: calc(2em - 1px); 

Объедините несколько идей и исследуйте!

Не обманывайте себя старыми иллюстрациями в моих примерах — спецификацию можно использовать для более современных дизайнов с фотографиями и тому подобным:

Цвет многоугольника

Посмотрите на CodePen (эта демонстрация слишком неудобна для встраивания).

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

Пожалуйста, принимайте участие, экспериментируйте и делитесь своими результатами, чтобы помочь развить спецификацию в то, что мы можем уверенно и счастливо использовать в будущем. Вы можете оставить отзыв W3C здесь или связаться с командой Adobe Web Platform.

Дальнейшая информация

Если вы очень заинтересованы и хотите узнать больше о спецификации CSS Shapes, проверьте следующие ссылки: