Потрясающая отзывчивая вёрстка с использованием CSS-областей

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

Поддержка

Области являются новой частью спецификации CSS, так что на данный момент они поддерживаются не везде, а в некоторых браузерах они находятся за флагом. Поддержка областей недавно была добавлена в iOS7 и Safari 7, также они поддерживаются Safari 6.1+. Команда Adobe составила список браузеров, поддерживающих разные новые возможности (включая области), и инструкции по их активации. Как бы то ни было, поддержка областей постоянно растёт. Полный список браузеров, которые поддерживают области и другие продвинутые возможности, можно увидеть на сайте Adobe на странице «Поддержка CSS-областей».

Введение в области

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

Чтобы использовать области, начните с создания потока с заданным названием: просто добавьте элементу с контентом свойство flow-into и присвойте ему название вашего потока в качестве значения. Затем для каждой области, которую вы хотите использовать в качестве контейнера для потока, укажите свойство flow-from с тем же названием потока в качестве значения. Содержимое первого элемента будет перетекать в остальные элементы-области. На данный момент браузеры требуют свойства с префиксом, но здесь мы используем версию без префикса:

#myContent {
    flow-into: myNamedFlow;
}

.myRegion {
    flow-from: myNamedFlow;
}

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

<div class="myRegion"></div>
<div class="myRegion"></div>
<div class="myRegion"></div>

<div id="myContent"></div>

При использовании областей распределяемый контент не является дочерним по отношению к элементам-областям — мы всего лишь меняем место отображения контента. С точки зрения DOM всё остаётся в исходном состоянии, поэтому контент не наследует стили от области, в которую он помещён. Вместо этого в спецификации определён псевдоселектор ::region(), который позволяет стилизировать контент в элементах-областях. Нужно задать этот псевдоселектор в качестве селектора области, а затем передать селектор элемента в качестве аргумента, обозначая для каких элементов будет применяться стиль в пределах конкретной области:

.myRegion::region(p){
    /*стили для абзацев(p), которые распределяются между областями*/
}

Использование областей в отзывчивом дизайне

Отзывчивый дизайн — это техника создания гибкой раскладки, которая изменяется в зависимости от контекста. Чтобы сделать элементы гибкими и адаптировать вёрстку для экранов разных размеров разработчики часто используют процентные значения и медиазапросы. Отзывчивый дизайн приспосабливает контент для любого экрана не требуя перестраивать дизайн или код.

Области упрощают создание отзывчивого дизайна. Чтобы убедиться, что контент поместится в свой контейнер, нам больше не нужно полагаться на height: auto, прописанный для каждого элемента. Вместо этого мы можем разрешить контенту распределяться между несколькими элементами раскладки. Это означает, что контент не диктует какой должна быть вёрстка, а скорее подстраивается под задуманный дизайн. Для последней области можно использовать height: auto, чтобы быть уверенными что она расширится, чтобы вместить весь оставшийся контент. Использование этого приёма можно увидеть в примере с CodePen, размещённом ниже:

Области и события

Для управления вёрсткой и обеспечения корректного отображения контента можно использовать JavaScript-события для областей. В спецификации областей описаны события, которые можно использовать при определённых состояниях. Событие regionoversetchange запускается когда для какой-либо области меняется свойство regionOverset: это может случиться когда пользователь изменяет размеры страницы, растягивая элемент-контейнер таким образом, что контент больше не заполняет некоторые области. regionOverset может принимать значения fit, overset или empty. Значение empty указывает, что внутри области нет контента. Свойство regionOverset принимает значение overset когда последняя область в цепочке не может вместить весь оставшийся контент, при этом часть контента становится недоступна.

Значение fit указывает на то, что контент заполнил область должным образом: полностью (если это одна из областей в середине цепочки) или частично (если это последняя область в цепочке). Результат срабатывания этих событий зависит от дизайна, контента и других аспектов вёрстки. Их можно использовать чтобы динамически добавлять и удалять области, или чтобы применить класс, изменяющий расположение элементов. Ниже можно увидеть пример с CodePen.

Примечание: в некоторых реализациях вместо события regionoversetchange вызывается regionlayoutupdate согласно предыдущей версии спецификации.

Области и медиазапросы

Области задаются исключительно в CSS, что делает очень простым их использование в сочетании с медиазапросами. Кроме изменения размеров и позиционирования элементов, можно также определять какие элементы будут использоваться в качестве областей. Также можно присвоить для области display: none, и она будет полностью исключена из цепочки. Благодаря этой возможности отдельные области можно легко скрыть со страницы не беспокоясь о целостности контента. Этот приём также можно использовать для отображения абсолютно разных макетов без необходимости измененять контент.

Области и свойства разрывов

CSS-области позаимствовали свойства разрывов из спецификации по многоколоночной вёрстке (multi-column layout specification), их можно использовать для контроля разбивки контента по областям. Эти свойства можно применить для элементов в потоке, чтобы указать, что внутри них должен быть разрыв или же наоборот — чтобы его избежать. Использование значения region для break-before или break-after приведёт к принудительному разрыву перед или после соответствующего элемента. Значение avoid-region может быть использовано для break-before, break-after и break-inside чтобы избежать разрывов перед, после или внутри элемента.

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

Примечание: В некоторых реализациях используются не предусмотренные стандартами свойства разрывов с префиксом region; например, region-break-before или — с вендорным префиксом — -webkit-region-break-before.

Отзывчивая вёрстка

Для областей с помощью медиазапросов применяется свойство break-after.

Области и единицы области просмотра

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

Однако можно использовать области для разбивки контента, сохраняя при этом переменный размер элементов при разных размерах экрана. Применение этого приёма можно увидеть в «Демо для слонов-сирот на National Geographic». На этой странице изображения и текст изменяются таким образом, чтобы сохранять высоту области просмотра. Области использованы для распределения потока контента по всем текстовым блокам, и они подстраиваются, когда пользователь уменьшает окно браузера.

демо

Использование областей с относительными единицами. Обратите внимание как точно изображение заполняет окно. (Крупнее)

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

На вебсайте Kindle Cloud Reader можно увидеть похожий двухстраничный разворот, однако здесь для управления вёрсткой используется JavaScript. Реализация такой вёрстки с помощью JavaScript очень затратна с точки зрения усилий со стороны разработчиков, к тому же настолько неэкономичный подход к управлению DOM обычно ведёт к снижению производительности. Мы можем использовать области, чтобы сделать то же самое с помощью существующих возможностей браузера, тем самым повышая производительность сайта и уменьшая время на разработку.

Отладка

Для работы с областями будет полезно иметь инструменты для управления и отладки. В панели инструментов разработчика в Chrome можно включить инструменты отладки областей. Подробные инструкции по включению этих инструментов можно найти в статье Кристиана Кантрелла (Christian Cantrell) «Поддержка CSS-областей в Веб-инспекторе». С помощью этих инструментов вы сможете увидеть все именованные потоки в документе, найти контент и цепочку областей, привязанных к каждому проименованному потоку, и получить визуальные подсказки о том, помещается ли контент в область, основываясь на значении свойства regionOverset.

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

отладка

В Webkit Nightly есть возможность просматривать код контейнеров областей, их порядок и цепочку областей

Материалы для дальнейшего чтения

Области открывают множество возможностей для разработки отзывчивого дизайна и дают уверенность, что контент будет отлично выглядеть на экранах любого размера. Один из отзывчивых сайтов, уникальная раскладка которого была создана с помощью областей — демо для компании по производству велосипедов от Adobe, созданная с использованием Edge Reflow. Подпишитесь на @adobeweb чтобы следить за последними новостями по областям и другим новинкам. Также рекомендуем просмотреть подборку от Adobe на CodePen, в которой продемонстрировано использование областей на практике; возможно, у вас возникнет желание скопировать код одного-двух примеров чтобы изучить различные варианты использования областей.

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