Журнальный макет для Интернета с CSS-областями и исключениями.

Кристиан Кантрелл
Christian Cantrell

Введение

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

Пример исключений CSS в действии
Пример исключений CSS в действии

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

Пример регионов CSS в действии
Пример регионов CSS в действии

CSS-регионы

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

Включение регионов CSS в Google Chrome

Начиная с версии 20 Chrome (точнее, версии 20.0.1132.57), регионы CSS включаются через интерфейс chrome://flags . Чтобы включить регионы CSS, выполните следующие действия:

  1. Откройте новую вкладку или окно в Chrome.
  2. Введите chrome://flags в адресной строке.
  3. Используйте поиск на странице (control/command + f) и найдите раздел «экспериментальные функции веб-платформы» .
  4. Нажмите ссылку Включить .
  5. Нажмите кнопку «Перезапустить сейчас» внизу.

Дополнительную информацию о флагах Chrome можно найти в моей публикации в блоге «Все о флагах Chrome» .

Перезапустив браузер, вы можете начать экспериментировать с регионами CSS.

Обзор регионов CSS

CSS Regions позволяет блоку семантически размеченного текста автоматически перетекать в «блоки» (в настоящее время элементы). На диаграмме ниже показано разделение текста (потока) и блоков (областей, в которые попадает текст):

Контент течет в определенные регионы
Контент течет в определенные регионы

Давайте посмотрим на реальный вариант использования CSS-регионов. Я не только разработчик в Adobe, но и писатель-фантаст. Я часто публикую свою работу в Интернете под лицензией Creative Commons, и чтобы она могла работать на максимальном количестве устройств и браузеров, я часто использую чрезвычайно простой формат, подобный этому:

Пример проекта «Нестилизованное человеческое наследие»
Пример проекта «Нестилизованное человеческое наследие»

Используя CSS-регионы, мне удалось создать интерфейс, который одновременно более интересен визуально и гораздо более функционален, поскольку по нему легче ориентироваться и удобнее читать:

Проект «Человеческое наследие» с указанием региона
Проект «Человеческое наследие» с регионами.

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

Проект «Человеческое наследие» с указанием регионов
Проект «Человеческое наследие» с указанием регионов

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

Создание именованного потока

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

<!DOCTYPE html>
<html>
<head>
    <style>
    #content {
        { % mixin flow-into: article; % }
    }

    .region {
        { % mixin flow-from: article; % }
        box-sizing: border-box;
        position: absolute;
        width: 200px;
        height: 200px;
        padding: 10px;
    }

    #box-a {
        border: 1px solid red;
        top: 10px;
        left: 10px;
    }

    #box-b {
        border: 1px solid green;
        top: 210px;
        left: 210px;
    }

    #box-c {
        border: 1px solid blue;
        top: 410px;
        left: 410px;
    }
    </style>
</head>
<body>
    <div id="box-a" class="region"></div>
    <div id="box-b" class="region"></div>
    <div id="box-c" class="region"></div>
    <div id="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eleifend dapibus felis, a consectetur nisl aliquam at. Aliquam quam augue, molestie a scelerisque nec, accumsan non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin cursus euismod nisi, a egestas sem rhoncus eget. Mauris non tortor arcu. Pellentesque in odio at leo volutpat consequat....
    </div>
</body>
</html>

Результат выглядит следующим образом:

Результат приведенного выше кода
Результат приведенного выше кода

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

Объектная модель CSS

Объектная модель CSS , или CSSOM, определяет API-интерфейсы JavaScript для работы с CSS. Ниже приведен список новых API, связанных с регионами CSS:

  • document.webkitGetNamedFlows() : функция, которая возвращает коллекцию именованных потоков, доступных в документе.
  • document.webkitGetNamedFlows().namedItem("article") : функция, которая возвращает ссылку на определенный именованный поток. Аргумент соответствует имени, указанному в качестве значения свойств CSS flow-into и from-from . Чтобы получить ссылку на именованный поток, указанный в приведенном выше фрагменте кода, необходимо передать строку «article».
  • WebKitNamedFlow : объектное представление именованного поля со следующими свойствами и функциями:
    • firstEmptyRegionIndex : целочисленное значение, указывающее на индекс первой пустой области, связанной с именованным потоком. См. getRegions() ниже, чтобы узнать, как получить коллекцию регионов.
    • name : строковое значение с именем потока.
    • overset : логическое свойство, которое:
      • false , когда содержимое именованного потока помещается в связанные регионы
      • true , когда контент не помещается и для размещения всего контента требуется больше регионов.
    • getContent() : функция, которая возвращает коллекцию со ссылками на узлы, входящие в именованный поток.
    • getRegions() : функция, которая возвращает коллекцию со ссылками на регионы, содержащие содержимое именованного потока.
    • getRegionsByContentNode(node) : функция, которая возвращает ссылку на регион, содержащий указанный узел. Это особенно полезно для поиска регионов, содержащих такие вещи, как именованные привязки.
  • событие webkitregionoversetchange . Это событие запускается в WebkitNamedFlow всякий раз, когда макет связанного контента изменяется по какой-либо причине (содержимое добавляется или удаляется, изменяется размер шрифта, изменяется форма региона и т. д.) и приводит к изменению свойства webkitRegionOverset региона. . Это событие полезно для прослушивания грубых изменений макета. Это индикатор того, что произошло что-то важное и макет может потребовать внимания, например: требуется больше регионов, некоторые регионы могут быть пустыми и т. д.
  • Событие webkitregionfragmentchange . Не реализовано на момент редактирования. Это событие запускается в WebkitNamedFlow всякий раз, когда по какой-либо причине изменяется макет связанного контента, аналогично webkitregionoversetchange , но независимо от каких-либо изменений в свойствах webkitRegionOverset . Это событие полезно для прослушивания детальных изменений макета, которые не обязательно влияют на весь макет именованного потока, например: контент перемещается из одного региона в другой, но общий контент по-прежнему помещается во все регионы.
  • Element.webkitRegionOverset : элементы становятся регионами, когда им назначено свойство CSS flow-from . Эти элементы имеют свойство webkitRegionOverset , которое, если они являются частью именованного потока, указывает, выходит ли содержимое потока за пределы региона. Возможные значения webkitRegionOverset:
    • «переполнение», если контента больше, чем может вместить регион
    • «подходит», если контент останавливается до конца региона
    • «пусто», если контент не достиг региона

Одним из основных применений CSSOM является прослушивание событий webkitregionoversetchange и динамическое добавление или удаление регионов для размещения различных объемов текста. Например, если объем форматируемого текста непредсказуем (возможно, созданный пользователем), если размер окна браузера изменяется или если изменяется размер шрифта, может потребоваться добавить или удалить области, чтобы учесть изменения в потоке. . Кроме того, если вы хотите организовать свой контент на страницах, вам понадобится механизм динамического изменения DOM, а также ваших регионов.

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

var flow = document.webkitGetNamedFlows().namedItem("article")
flow.addEventListener("webkitregionoversetchange", onLayoutUpdate);

function onLayoutUpdate(event) {
    var flow = event.target;
    
    // The content does not fit
    if (flow.overset === true) {
    addRegion();
    } else {
    regionLayoutComplete();
    }
}

function addRegion() {
    var region = document.createElement("div");
    region.style = "flow-from: article";
    document.body.appendChild(region);
}

function regionLayoutComplete() {
    // Finish up your layout.
}

Дополнительные демо-версии доступны на странице образцов CSS-регионов .

Шаблоны страниц CSS

Использование CSSOM, вероятно, является наиболее мощным и гибким способом реализации таких вещей, как разбиение на страницы и адаптивный макет, но Adobe работает с инструментами для публикации текста и настольных компьютеров достаточно долго, чтобы знать, что дизайнерам и разработчикам также понадобится более простой способ получить относительно общие возможности пейджинга. Поэтому мы работаем над предложением под названием «Шаблоны страниц CSS», которое позволяет полностью декларативно определять поведение страниц.

Давайте рассмотрим распространенный вариант использования шаблонов страниц CSS. В приведенном ниже фрагменте кода показано использование CSS для создания двух именованных потоков: «article-flow» и «timeline-flow». Кроме того, он определяет третий селектор, называемый «комбинированными статьями», внутри которого будут содержаться два потока. Простое включение свойства overflow-style в селектор «комбинированных статей» указывает на то, что контент должен автоматически перемещаться вдоль оси X или горизонтально:

<style>
    #article {
    { % mixin flow-into: article-flow; % }
    }

    #timeline {
    { % mixin flow-into: timeline-flow; % }
    }

    #combined-articles {
    overflow-style: paged-x;
    }
</style>

Теперь, когда потоки определены и задано желаемое поведение при переполнении, мы можем создать сам шаблон страницы:

@template {
    @slot left {
    width: 35%;
    float: left;
    { % mixin flow-from: article-flow; % }
    }

    @slot time {
    width: 25%;
    float: left;
    { % mixin flow-from: timeline-flow; % }
    }

    @slot right {
    width: 35%;
    float: left;
    { % mixin flow-from: article-flow; % }
    }
}

Шаблоны страниц определяются с использованием нового синтаксиса «at». В приведенном выше фрагменте кода мы определяем три слота, каждый из которых соответствует столбцу. Текст из «потока статей» будет проходить через столбцы слева и справа, а текст из «потока временной шкалы» будет заполняться столбцом посередине. Результат может выглядеть примерно так:

Пример шаблонов страниц
Пример шаблонов страниц

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

Шаблоны страниц CSS все еще являются предложением, однако у нас есть прототип , который использует «прокладку» JavaScript (также называемую полифиллом ), чтобы вы могли экспериментировать с ними уже сейчас.

Чтобы узнать больше о регионах CSS в целом, посетите страницу «Регионы CSS» на сайте html.adobe.com .

Исключения CSS

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

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

Пример исключений CSS в действии
Пример исключений CSS в действии

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

Текст растекается в многоугольники неправильной формы.
Текст растекается в многоугольники неправильной формы.

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

Дополнительную информацию об исключениях CSS см. на странице исключений CSS на сайте html.adobe.com , а более подробный обзор работы Adobe над базовой технологией исключений CSS см. в записи блога Ханса Мюллера под названием «Горизонтальный блок: пересечение многоугольников для исключений CSS». .

Текущее состояние регионов CSS и исключений CSS

Впервые я публично рассказал о регионах CSS и исключениях CSS на конференции Adobe Developer Pod на Google I/O 2011. В то время я показывал демоверсии в нашем собственном браузере-прототипе. Прием был восторженным, однако возникло ощутимое чувство разочарования, когда зрители обнаружили, что ни одна из представленных мной функций пока недоступна ни в одном из основных браузеров.

В этом году (2012) я снова был на Google I/O, на этот раз в качестве ведущего вместе с моим коллегой Винсентом Харди и Алексом Данило из Google ( презентацию можно посмотреть здесь ). Всего год спустя около 80% спецификации CSS Regions было реализовано в WebKit и уже присутствует в самой последней версии Google Chrome (обратите внимание, что CSS Regions в настоящее время необходимо включать через chrome://flags ). Предварительная поддержка регионов CSS появилась даже в Chrome для Android:

Регионы в Chrome для Android
Регионы в Chrome для Android

Кроме того, как регионы CSS, так и исключения CSS реализованы в предварительной версии Internet Explorer 10 и в настоящее время включены в дорожную карту Mozilla для Firefox на 2012 год. Следующая основная версия Safari должна поддерживать большую часть спецификации регионов CSS, а последующие обновления должны включать оставшуюся часть.

Ниже приведен подробный график прогресса, которого мы достигли в области CSS-регионов и исключений CSS с момента нашего первоначального предложения W3C в апреле 2011 года:

Регион и прогресс исключения
Регион и прогресс исключения

Заключение

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