Pull to refresh

Будущее CSS разметки

CSS *
Питер Гасстон, автор книги по CSS3, опубликовал статью под названием The future of CSS layouts, перевод которой специально для читателей хабра представлен ниже.

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

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

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

Консорциум W3C и создатели браузеров в курсе этих проблем и работают над рядом решений. Лидером среди них является (как не удивительно) Internet Explorer. Похоже, что IE10 будет предвестником новой эры CSS разметки, которая позволит создавать отличные, динамические и привлекательные сайты, используя недосягаемые ранее возможности.

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


Колонки


Распределение контента между несколькими колонками является основным элементом печати и модуль CSS Multi-Columns даёт такую же возможность для web. Для создания колонок можно использовать два способа, каждый из них использует различные свойства (родительского элемента). В первом случае напрямую задаётся количество колонок, среди которых необходимо распределить текст. Например, этот код создаст три колонки одинаковой ширины, заполняя в сумме ширину родительского элемента:

div { column-count: 3; }

Во втором способе ширина колонок фиксирована, они будут повторяться до тех пор, пока не заполнят ширину родительского элемента. В этом примере ширина колонки установлена в 140px, значит в блоке шириной 800px должно появиться пять колонок:

div { column-width: 140px; }

По умолчанию, зазор между колонками равен 1em, но его можно сменить, используя свойство column-gap. Также между колонками можно разместить разделительные линии с помощью column-rule, похожий по синтаксису на свойство border. Представленный ниже код создаст пунктирную линию шириной 2px, а также установит отступ между колонками в 28px (разделитель будет располагаться посредине):

div {
	column-gap: 28px;
	column-rule: 2px dotted #ccc;
}

Если хотите посмотреть результат, взгляните на пример реализации CSS колонок. Для того, чтобы увидеть три колонки, необходимо использовать Firefox, Chrome, Safari, Opera 11.1 или IE10 Platform Preview (IE10PP). Либо посмотрите на представленный ниже скриншот.

CSS Columns provides an easy way to distribute long blocks of content into a more compact horizontal space

С колонками можно делать разные вещи. Практический пример их использования есть в Википедии, в секции примечаний, где используется column-count. В Firefox многоколоночность реализована с префиксом -moz-, в Chrome и Safari с префиксом -webkit-, в Opera 11.1 и IE10PP без префиксов.

Flexible box


Модуль Flexible Box Layout (FlexBox) позволяет автоматически изменять размеры элементов внутри родительских без необходмости вычислять значения высоты и ширины. Например, представьте, что у вас есть два дочерних элемента и вы хотите, чтобы они заполнили родительский (который имеет различную ширину) таким образом, чтобы оба блока имели одинаковую ширину. Это можно сделать, используя процентные значения, однако, в случае наличия бордюров и отступов задача становится сложной. Решение с помощью FlexBox намного проще:

.parent { display: box; }
.child-one, .child-two { box-flex: 1; }

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

.child-one { box-flex: 1; }
.child-two { box-flex: 2; }

Когда два элемента распределятся внутри родительского, ширина .child-two будет увеличиваться на два пикселя на каждый один пиксель .child-one. Если ширина родительского будет составлять 260px, а каждый дочерний по 100px, оставшиеся 60px распределятся так, что 40px будет отведено .child-two и 20px для .child-one.

Эту концепцию легче будет понять на примере использования FlexBox (необходим Firefox, Chrome, Safari или IE10PP). Попробуйте изменить размер окна браузера и обратите внимание на масштабирование.

По аналогии динамического изменения размера элементов, FlexBox позволяет также применять свойства к родительскому, управляющему распределением пустого пространства, устанавливающему позиции дочерних элементов. Свойство box-align влияет на ширину дочерних элементов, а парное свойство box-pack на их высоту. Ниже показано, как это работает:

.parent {
	box-align: center;
	box-pack: center;
	display: box;
	height: 200px; width: 200px;
}

.child {
	box-flex: 0;
	height: 100px; width: 100px;
}

Элемент .child имеет значение свойства box-flex равным 0, таким образом, он не будет динамически менять размер, а также он в два раза меньше по высоте и ширине родительского элемента, который, в свою очередь, центрирован с помощью свойств box-align и box-pack. То есть, дочерний блок будет центрирован по вертикали и горизонтали.

We showed how to make layouts with FlexBox in more detail in a previous article

На данный момент FlexBox реализован в Firefox, Chrome, Safari и IE10PP с соответствующими браузерам префиксами (-moz-, -webkit-, and -ms-), а также существует JS Polyfill, Flexie, с которым можно поэкспериментировать. Помните, что синтакс изменился, детали в последних спеках.

Таблица


Совершенно новым в IE10PP является система табличной разметки. Перед её использованием необходимо определиться со строками и колонками. Для колонок можно использовать значения длины, auto keyword и новую единицу измерения fr (сокращение от fraction, относительное количество). Посмотрите на этот пример:

div {
	display: grid;
	grid-columns: 1fr 3fr 1fr;
	grid-rows: 100px auto 12em;
}

Этот код создаст таблицу из трех колонок, центральная из которых будет в три раза шире левой и правой, а также из трех строк, где верхняя будет 100px по высоте, нижняя 12em, а средняя расширится по высоте автоматически, в зависимости от длины контента.

Теперь, когда у нас есть таблица, можно в ней разместить контент. Используя элементы HTML5, можно создать, действительно, очень простую разметку страницы:

header { grid-column: 1; grid-column-span: 3; grid-row: 1; }
nav { grid-column: 1; grid-row: 2; }
article { grid-column: 2; grid-row: 2; }
aside { grid-column: 3; grid-row: 2; }
footer { grid-column: 1; grid-column-span: 3; grid-row: 3; }

Вматриваясь в код, можно заметить, что контент на странице распределен по строкам и столбцам с помощью, соответственно, свойств grid-row и grid-column. Элемент article размещен во вторую колонку второй строки — центр таблицы 3х3. Также используется свойство column-span для элементов header и footer, которое растягивает их на все три колонки (подобно действует свойство row-span, которое здесь не использовалось).

Демо разметки можно посмотреть в примере использования CSS Grid, но нужна платформа IE10. Если её нет, то просто взгляните на скриншот.

A pretty standard three-column grid layout, built using CSS Grid properties only

Упомянутые выше свойства полностью внедрены в IE10PP, поэтому можно с ними экспериментировать прямо сейчас. Однако, множество свойств всё ещё не реализовано.

Шаблон


Другим подходом к табличному представлению является модуль Template Layout. Он использует немного иной синтаксис, где сперва необходимо присвоить позицию блокам, используя буквенный символ и свойство position:

header { position: a; }
nav { position: b; }
article { position: c; }

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

div { display: 'abc'; }

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

div {
display:
    'baa'
    'bcc';
}

Template Layout ещё не используется браузерами, но уже есть хороший скрипт polyfill на jQuery, который позволит поэкспериментировать, именно он использован в примере по ссылке. Результат выглядит также, как в примере с табличной разметкой, но код совсем другой.

На демо-странице используется JavaScript, поэтому должно сработать на всех современных браузерах. Табличная разметка, возможно, будет поддерживать и синтаксис шаблона, как на приведенном ниже примере:

header { grid-cell: a; }
article { grid-cell: b; }
div {
	display: grid;
	grid-template: 'a' 'b';
}

По функционалу этот код идентичен свойствам Template Layout, но также ещё не внедрён (а может быть никогда и не будет).

Позиционируемые плавающие блоки


Текущее свойство float позволяет тексту обтекать элемент слева или справа, но расширенное свойство в IE10PP позволяет усовершенствовать плавающий элемент, размещая его в любом месте, а соседствующий контент будет по прежнему обтекать этот блок. Для этого всего лишь понадобилось новое значение для свойства float:

div {
	float: positioned;
	left: 200px; position: absolute; top: 100px; width: 250px;
}

Этот код создаст элемент 250px по ширине, расположенный слева на 200px и сверху на 100px от родительского объекта. По умолчанию, любой другой контент внутри родительского будет обтекать позиционируемый элемент со всех сторон, но это можно изменить различными значениями свойства wrap-type, например, когда текст обтекает элемент только сверху и снизу:

div { wrap-type: top-bottom; }

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

div {
	float: positioned;
	grid-column: 2;
	grid-row: 2;
}

Если у вас имеется IE10PP, то можно посмотреть демо позиционируемого плавающего блока. Если нет, то результат показан на скриншоте ниже, его невозможно реализовать текущими возможностями CSS.

A new style of layout only possible with new CSS properties, including Positioned Floats

Exclusions


Свойство float позволяет лишь прямоугольным элементам быть обтекаемыми, но в докуменации предусмотрены обтекания по форме. Идея пришла после использования модуля CSS Exclusions. В нём имеются два ключевых свойства. Первое, wrap-shape, позволяет создавать элипсы, прямоугольники или многоугольники, которые будут задавать форму обтекаемого контентом блока, например:

div { wrap-shape: circle(50%, 50%, 100px); }

Этот код создаст окружность с радиусом 100px, которая будет центрирована в родительском элементе. Можно использовать функцию polygon() для создания любой фигуры, указывая координатные пары, разделенные пробелом, например для треугольника:

div { wrap-shape: polygon(0,100px 100px,100px 50px,0); }

Когда уже имеется заданная фигура, внутренний контент можно сделать обтекаемым по этой фигуре, используя второе свойство wrap-shape-mode, как здесь:

div {
	wrap-shape: circle(50%, 50%, 100px);
	wrap-shape-mode: around;
}

Работу CSS Exclusions в действии можно посмотреть, скачав прототип для Mac или Windows с лаборатории Adobe. Там имеется полная документация и несколько очень классных демо-файлов, например, такой:

The text flows around the shape of the image thanks to CSS Exclusions

Области


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

.content { flow: foo; }
.target1, .target2 { content: from(foo); }

Здесь контент будет браться из элемента .content, а далее распределятся сперва по элементу .target1 и если блока не хватит для отображения контента, то он будет продолжать отображаться в .target2. Контент не будет дублироваться в блоках, он будет начинаться в первом и продолжаться во втором (если необходимо). Чтобы лучше понять, просто взгляните на изображение ниже.

Content from an element (not shown) flowing across three different elements, using CSS Regions

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

Спеки по CSS областям ещё не были внедрены в браузеры, но по аналогии с Exclusions, можно использовать прототип с лаборатории Adobe и попробовать функционал самостоятельно.

Заключение


Пока что неясно, какие из новых модулей разметки (из FlexBox и Колонок) будут полностью внедрены в браузеры. Что касается плавающих блоков и Exclusions, хотелось бы их скрестить из-за похожести функционала (возможно, так и будет). Табличная разметка тесно связана с разметкой шаблонами и, несомненно, можно ожидать её появление в IE10. CSS области уже внедрены в одной из ветвей WebKit, и, вероятно, появятся в WebKit-браузерах (Safari, Chrome и других) очень скоро.

Таким образом, можно прогнозировать, что с некоторыми изменениями в синтаксисе, всё описанное выше будет использоваться в CSS3 в будущем. Очень хорошо, если это произойдёт, так как, в этом случае, новые методы позволят с минимальными затратами создавать очень продуманные сайты всего через несколько лет.
Tags:
Hubs:
Total votes 97: ↑93 and ↓4 +89
Views 13K
Comments Comments 76