Начало работы с фигурами CSS

Обертывание контента вокруг пользовательских путей

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

Формы можно определить вручную или вывести из изображений.

Давайте рассмотрим очень простой пример.

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

Извлечение фигуры из изображения
<img class="element" src="image.png" />
<p>Lorem ipsum…</p>

<style>
.element{
  shape-outside: url(image.png);
  shape-image-threshold: 0.5;
  float: left;
}
</style>

Объявление CSS shape-outside: url(image.png) сообщает браузеру, что нужно извлечь фигуру из изображения.

Свойство shape-image-threshold определяет минимальный уровень непрозрачности пикселей, который будет использоваться для создания фигуры. Его значение должно находиться в диапазоне от 0.0 (полностью прозрачный) до 1.0 (полностью непрозрачный). Итак, shape-image-threshold: 0.5 означает, что для создания фигуры будут использоваться только пиксели с непрозрачностью 50% и выше.

Свойство float здесь является ключевым. Хотя свойство shape-outside определяет форму области, вокруг которой будет обтекаться содержимое, без float вы не увидите эффектов формы.

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

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

Создание фигур вручную

Помимо извлечения фигур из изображений, вы также можете кодировать их вручную. Вы можете выбрать одно из нескольких функциональных значений для создания фигур: circle() , ellipse() , inset() и polygon() . Каждая функция формы принимает набор координат и связана с эталонным полем, которое устанавливает систему координат. Подробнее о справочных полях чуть позже.

Функция круг()

Иллюстрация значения формы круга()

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

.element{
  shape-outside: circle(50%);
  width: 300px;
  height: 300px;
  float: left;
}

В приведенном выше примере контент будет обтекать внешнюю часть кругового пути. Единственный аргумент 50% определяет радиус круга, который в данном конкретном случае составляет половину ширины или высоты элемента. Изменение размеров элемента повлияет на радиус формы круга. Это базовый пример того, как CSS-фигуры могут быть адаптивными.

Прежде чем идти дальше, небольшое отступление: важно помнить, что CSS-фигуры влияют только на форму плавающей области вокруг элемента. Если у элемента есть фон, он не будет обрезан фигурой. Чтобы добиться этого эффекта, вы должны использовать свойства из CSS Masking — либо clip-path , либо Mask-image . Свойство clip-path очень удобно, поскольку оно соответствует той же нотации, что и CSS-фигуры, поэтому вы можете повторно использовать значения.

Иллюстрация формы `circle()` + клип-путь

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

Вернемся к форме круга.

При использовании процентов для радиуса круга значение фактически вычисляется по несколько более сложной формуле : sqrt(ширина^2 + высота^2) / sqrt(2). Это полезно понимать, потому что это поможет вам представить, какой будет результирующая форма круга, если размеры элемента не равны.

В координатах функции формы можно использовать все типы единиц измерения CSS — px, em, rem, vw, vh и т. д. Вы можете выбрать тот, который является достаточно гибким или жестким для ваших нужд.

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

.element{
  shape-outside: circle(50% at 0 0);
}

Это расположит центр круга в начале системы координат. Что такое система координат? Здесь мы вводим справочные поля.

Справочные поля для фигур CSS

Эталонная рамка — это виртуальная рамка вокруг элемента, которая устанавливает систему координат, используемую для рисования и позиционирования фигуры. Начало системы координат находится в верхнем левом углу, при этом ось X направлена ​​вправо, а ось Y — вниз.

Система координат для фигур CSS

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

Следующие два объявления CSS дают идентичные результаты:

.element{
  shape-outside: circle(50% at 0 0);
  /* identical to: */
  shape-outside: circle(50% at 0 0) margin-box;
}

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

.element{
  shape-outside: circle(50% at 0 0) margin-box;
  margin: 100px;
}

Начало системы координат теперь находится за пределами области содержимого элемента (100 пикселей вверх и 100 пикселей влево), как и центр круга. Вычисленное значение радиуса круга также увеличивается, чтобы учесть увеличение поверхности системы координат, установленной полем ссылки margin-box .

Система координат поля-поля с полем и без него
На выбор предлагается несколько вариантов справочного поля: «поле поля», «пограничное поле», «поле заполнения» и «поле содержимого». Их имена подразумевают их границы. Ранее мы объяснили «поле поля». «border-box» ограничен внешними краями границ элемента, «padding-box» ограничен отступами элемента, а «content-box» идентичен фактической площади поверхности, используемой содержимым внутри элемента. элемент.
Иллюстрация всех справочных полей

Одновременно с объявлением shape-outside можно использовать только один ссылочный блок. Каждый эталонный блок будет влиять на форму по-своему, а иногда и незаметно. Есть еще одна статья, которая углубляется и помогает вам понять справочные поля для фигур CSS .

Функция эллипс()

Иллюстрация значения формы эллипса()

Эллипсы выглядят как сплющенные круги. Они определяются как ellipse(rx ry at cx cy) , где rx и ry — радиусы эллипса по осям X и Y, а cx и cy — координаты центра эллипса.

.element{
  shape-outside: ellipse(150px 300px at 50% 50%);
  width: 300px;
  height: 600px;
}

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

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

.element{
  shape-outside: ellipse(closest-side farthest-side at 50% 50%);
  /* identical to: */
  shape-outside: ellipse(150px 300px at 50% 50%);
  width: 300px;
  height: 600px;
}

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

Те же ключевые слова farthest-side и closest-side также можно использовать для радиуса в функции формы circle() .

Функция многоугольника()

Иллюстрация значения формы многоугольника ()

Если круги и эллипсы слишком ограничены, функция формы многоугольника открывает целый мир возможностей. Формат — polygon(x1 y1, x2 y2, ...) где вы указываете пары координат xy для каждой вершины (точки) многоугольника. Минимальное количество пар для указания многоугольника — три, треугольник.

.element{
  shape-outside: polygon(0 0, 0 300px, 300px 600px);
  width: 300px;
  height: 600px;
}

Вершины размещаются в системе координат. Для адаптивных полигонов вы можете использовать процентные значения для некоторых или всех координат.

.element{
  /* polygon responsive to font-size*/
  shape-outside: polygon(0 0, 0 100%, 100% 100%);
  width: 20em;
  height: 40em;
}

Существует необязательный параметр fill-rule , импортированный из SVG , который указывает браузеру, как учитывать «внутренность» многоугольника в случае самопересекающихся путей или замкнутых фигур. Джони Триталл очень хорошо объясняет , как свойство правила заполнения работает в SVG. Если не определено, fill-rule по умолчанию имеет nonzero .

.element{
  shape-outside: polygon(0 0, 0 100%, 100% 100%);
  /* identical to: */
  shape-outside: polygon(nonzero, 0 0, 0 100%, 100% 100%);
}

Функция вставки()

Функция формы inset() позволяет создавать прямоугольные фигуры, вокруг которых можно обтекать контент. Это может показаться нелогичным, учитывая первоначальную предпосылку, что CSS Shapes освобождает веб-контент от простых блоков. Вполне может быть. Мне еще предстоит найти вариант использования inset() который еще не достижим с помощью чисел с плавающей запятой и полей или с помощью polygon() . Хотя inset() обеспечивает более читаемое выражение для прямоугольных фигур, чем polygon() .

Полное обозначение функции вставки формы: inset(top right bottom left border-radius) . Первые четыре аргумента позиции представляют собой смещения внутрь от краев элемента. Последний аргумент — это радиус границы прямоугольной формы. Это необязательно, поэтому вы можете его не указывать. Он соответствует сокращенному обозначению border-radius которое вы уже используете в CSS.

.element{
  shape-outside: inset(100px 100px 100px 100px);
  /* yields a rectangular shape which is 100px inset on all sides */
  float: left;
}

Создание фигур из справочных блоков

Если вы не укажете функцию формы для свойства shape-outside , вы можете разрешить браузеру получать форму из поля ссылки элемента. Поле ссылки по умолчанию — margin-box . Пока ничего экзотического, поплавки уже так работают. Но применяя эту технику, вы можете повторно использовать геометрию элемента. Давайте посмотрим на свойство border-radius .

Если вы используете его для скругления углов плавающего элемента, вы получите эффект обрезки, но плавающая область останется прямоугольной. Добавьте shape-outside: border-box , чтобы обернуть контур, созданный border-radius .

Извлечение формы из border-radius элемента с помощью поля ссылки border-box
.element{
  border-radius: 50%;
  shape-outside: border-box;
  float: left;
}

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

Создание смещенной цитаты с использованием поля ссылки на поле содержимого

Эффекта смещения кавычки можно добиться, используя только свойства float и поля. Но для этого вам необходимо расположить элемент цитаты в дереве HTML в той точке, где вы хотите, чтобы он отображался.

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

.pull-quote{
  shape-outside: content-box;
  margin-top: 200px;
  float: left;
}

Мы явно устанавливаем поле ссылки на content-box для системы координат фигуры. В этом случае объем содержимого в кавычке определяет форму, вокруг которой будет обтекаться внешний контент. Свойство margin-top используется здесь для позиционирования (смещения) цитирования независимо от его положения в дереве HTML.

Поле формы

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

.element{
  shape-outside: circle(40%);
  shape-margin: 1em;
  float: left;
}

Эффект аналогичен тому, к которому вы привыкли при использовании обычного свойства margin , но свойство shape-margin влияет только на пространство вокруг значения shape-outside . Он добавит пространство вокруг фигуры только в том случае, если для него есть место в системе координат. Вот почему в примере выше радиус круга установлен на 40%, а не на 50%. Если бы радиус был установлен на 50%, круг занял бы все пространство в системе координат, не оставляя места для эффекта shape-margin . Помните, что форма в конечном итоге ограничивается margin-box элемента (элемент плюс окружающий его margin ). Если фигура больше и выходит за пределы, она будет обрезана до margin-box , и в итоге вы получите прямоугольную форму.

Важно понимать, что shape-margin принимает только одно положительное значение. Он не имеет длинной записи. Что вообще такое shape-margin-top для круга?

Анимация фигур

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

Вы можете анимировать радиусы и центры фигур circle() и ellipse() , если они определены в значениях, которые браузер может интерполировать. Возможен переход от circle(30%) к circle(50%) . Однако анимация между circle(closest-side) и circle(farthest-side) задушит браузер.

.element{
  shape-outside: circle(30%);
  transition: shape-outside 1s;
  float: left;
}

.element:hover{
  shape-outside: circle(50%);
}
GIF анимированного круга

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

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

.element{
  /* four vertices (looks like rectangle) */
  shape-outside: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  transition: shape-outside 1s;
}

.element:hover{
  /* four vertices, but second and third overlap (looks like triangle) */
  shape-outside: polygon(0 0, 100% 50%, 100% 50%, 0 100%);
}
GIF анимированного треугольника

Обертывание содержимого внутри фигуры

Снимок экрана: демонстрация «Алисы в Стране чудес» с использованием фигур CSS для переноса контента

Первоначальный проект спецификации CSS Shapes включал свойство shape-inside , которое позволяло помещать содержимое внутрь фигуры. Какое-то время даже были реализации в Chrome и Webkit. Но размещение произвольно позиционированного контента внутри пользовательского пути требует гораздо больше усилий и исследований, чтобы охватить все возможные сценарии и избежать ошибок. Вот почему свойство shape-inside было перенесено в CSS Shapes Level 2 , а его реализации были отозваны.

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

<div>
  <div class='left-shape'></div>
  <div class='right-shape'></div>

  Lorem ipsum...
</div>

Положение элементов .left-shape и .right-shape в верхней части контейнера важно, поскольку они будут перемещаться влево и вправо, чтобы обрамлять содержимое.

.left-shape{
  shape-outside: polygon(0 0, ...);
  float: left;
  width: 50%;
  height: 100%;
}

.right-shape{
  shape-outside: polygon(50% 0, ...);
  float: right;
  width: 50%;
  height: 100%;
}
Иллюстрация обходного пути shape-inside для демо-версии Алисы

При таком стиле две плавающие стойки занимают все пространство внутри элемента, а свойства shape-outside выделяют место для остального содержимого.

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

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

В демонстрации CSS-фигур «Алиса в стране чудес» мы использовали положение прокрутки для изменения верхнего поля содержимого. Текст сжимается между двумя плавающими элементами. Когда он движется вниз, он должен переключаться в соответствии с shape-outside двух плавающих элементов. Это создает впечатление, что текст проваливается в кроличью нору, и это добавляет впечатлений от повествования. Граничит безвозмездно? Может быть. Но выглядит круто.

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

Прогрессивное улучшение

Начните с предположения, что браузер не поддерживает CSS-фигуры, и опирайтесь на это, когда обнаружите эту функцию. Modernizr — хорошее решение для обнаружения функций. В разделе «Неосновные обнаружения» есть тест для CSS-фигур.

Некоторые браузеры обеспечивают обнаружение функций в CSS с помощью правила @supports без необходимости использования внешних библиотек. Google Chrome, который также поддерживает фигуры CSS, понимает правило @supports . Вот как вы можете использовать его для постепенного улучшения:

.element{
  /* styles for all browsers */
}

@supports (shape-outside: circle(50%)){
  /* styles only for browsers which support CSS Shapes */
  .element{
    shape-outside: circle(50%);
  }
}

Леа Веру написала больше о том , как использовать правило CSS @supports .

Устранение неоднозначности из исключений CSS

То, что мы знаем сегодня как CSS-фигуры, на заре появления спецификации называлось CSS-исключениями и фигурами. Смена именования может показаться нюансом, но на самом деле она очень важна. CSS Exclusions , теперь отдельная спецификация, позволяет обертывать контент вокруг элементов, расположенных произвольно, без необходимости использования свойства float. Представьте себе, что контент оборачивается вокруг абсолютно позиционированного элемента; это вариант использования исключений CSS. CSS-фигуры просто определяют путь, по которому будет переноситься контент.

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

Инструменты для работы с CSS-фигурами

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

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

Brackets : расширение CSS Shapes Editor для Brackets использует режим предварительного просмотра редактора кода в реальном времени для наложения интерактивного редактора для редактирования значений формы.

Google Chrome : расширение CSS Shapes Editor для Google Chrome расширяет инструменты разработчика браузера элементами управления для создания и редактирования фигур. Он помещает интерактивный редактор поверх выбранного элемента.

Инспектор в Google Chrome имеет встроенную поддержку выделения фигур. Наведите указатель мыши на элемент со свойством shape-outside , и он загорится, иллюстрируя форму.

Формы из изображений . Если вы предпочитаете создавать изображения и извлекать из них формы в браузере, Ребекка Хаук написала хороший учебник для Photoshop .

Polyfill : Google Chrome — первый крупный браузер, поддерживающий CSS-фигуры. В ближайшее время ожидается поддержка этой функции в iOS 8 и Safari 8 от Apple. Другие поставщики браузеров могут рассмотреть возможность ее реализации в будущем. До тех пор существует полифил CSS Shapes, обеспечивающий базовую поддержку.

Заключение

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

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

Большое спасибо Перл Чен, Алану Стернсу и Золтану Хорвату за рецензирование этой статьи и предоставление ценной информации.