Mise en page de type magazine pour le Web avec des régions et des exclusions CSS

Christian Cantrell
Christian Cantrell

Introduction

Le Web est une plate-forme extrêmement puissante pour le texte, un domaine dans lequel Adobe possède une grande expérience et une grande expertise. Lorsque nous avons cherché des moyens de faire progresser le Web, il nous a semblé évident de commencer par améliorer les fonctionnalités textuelles du Web. Le Web suppose généralement une orientation verticale du texte sur une seule colonne. Bien qu'il soit possible de faire passer le texte autour des graphiques et même de le mettre en forme dans plusieurs colonnes avec CSS, il est toujours très difficile d'obtenir une mise en page semblable à celle d'un magazine sur le Web. Avec les régions CSS et les exclusions CSS, Adobe est à la pointe des efforts visant à apporter la puissance de la PAO aux navigateurs modernes. Par exemple, dans la capture d'écran ci-dessous, les exclusions CSS sont utilisées pour faire défiler le texte le long du contour de la montagne:

Exemple d'exclusions CSS en action
Exemple d'exclusions CSS en action

Le document de la capture d'écran ci-dessous utilise également des exclusions CSS pour permettre au texte de s'enrouler autour des formes des images, ainsi que des régions CSS pour mettre en forme le texte en colonnes et autour d'une citation:

Exemple d'utilisation des régions CSS
Exemple d'utilisation des régions CSS

Régions CSS

Avant d'entrer dans les détails des régions CSS, je vais vous expliquer comment les activer dans Google Chrome. Une fois que vous avez activé les régions CSS, vous pouvez essayer certains des exemples référencés dans cet article et créer les vôtres.

Activer les régions CSS dans Google Chrome

Depuis la version 20 de Chrome (version 20.0.1132.57, pour être exact), les régions CSS sont activées via l'interface chrome://flags. Pour activer les régions CSS, procédez comme suit:

  1. Ouvrez un nouvel onglet ou une nouvelle fenêtre dans Chrome.
  2. Saisissez chrome://flags dans la barre d'adresse.
  3. Utilisez la fonctionnalité Rechercher dans la page (Ctrl/Cmd+F) et recherchez la section "Fonctionnalités expérimentales de la plate-forme Web".
  4. Cliquez sur le lien Activer.
  5. Cliquez sur le bouton Relaunch Now (Redémarrer maintenant) en bas de l'écran.

Pour en savoir plus sur les options de Chrome, consultez mon article de blog sur les options Chrome.

Une fois votre navigateur relancé, vous pouvez commencer à tester les régions CSS.

Présentation des régions CSS

Les régions CSS permettent à un bloc de texte marqué sémantiquement de s'écouler automatiquement dans des "boîtes" (actuellement des éléments). Le diagramme ci-dessous montre la séparation du texte (le flux) et des cases (les régions dans lesquelles le texte s'écoule):

Le contenu est diffusé dans des régions définies
Flux de contenu vers des régions définies

Examinons un cas d'utilisation concret des régions CSS. En plus d'être développeur chez Adobe, je suis également écrivain de science-fiction. Je publie fréquemment mes travaux en ligne sous licence Creative Commons. Pour qu'ils fonctionnent sur le plus grand nombre d'appareils et de navigateurs possible, j'utilise souvent un format extrêmement simple, semblable à celui-ci:

Exemple de projet Human Legacy sans style
Exemple de projet ancien non stylisé sur les ressources humaines

Grâce aux régions CSS, j'ai pu créer une expérience à la fois plus visuellement intéressante et beaucoup plus fonctionnelle, car elle est plus facile à parcourir et plus confortable à lire:

Human Legacy Project affichant la région
Human Legacy Project with Regions.

À des fins de démonstration, j'ai ajouté la possibilité de révéler les régions CSS dans ce prototype. La capture d'écran ci-dessous montre comment les régions sont disposées de manière à donner l'impression d'être des colonnes qui entourent un graphique et une citation au centre:

Human Legacy Project affichant les régions
Human Legacy Project showing Regions

Vous pouvez tester ce prototype (et consulter le code source) ici. Utilisez les touches fléchées pour naviguer, puis appuyez sur la touche Esc pour afficher les régions. Vous trouverez également d'autres prototypes sur cette page.

Créer un flux nommé

Le CSS requis pour que le texte d'un bloc s'affiche dans les régions est extrêmement simple. L'extrait de code ci-dessous attribue un flux nommé "article" à une div avec l'ID "content", et attribue ce même flux nommé "article" à tout élément de la classe "region". Le texte contenu dans l'élément "content" s'affichera automatiquement dans tous les éléments de la classe "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>

Le résultat ressemble à ceci :

Résultat du code ci-dessus
Résultat du code ci-dessus

Notez que le texte dans le div "content" n'a aucune connaissance de sa présentation. En d'autres termes, il peut rester entièrement sémantiquement intact même lorsqu'il circule dans différentes régions. De plus, comme les régions ne sont que des éléments, elles sont positionnées et dimensionnées à l'aide du CSS comme n'importe quel autre élément. Elles sont donc parfaitement compatibles avec les principes du responsive design. Désigner des éléments dans le cadre d'un flux nommé signifie simplement que le texte spécifié s'affiche automatiquement dans ces éléments.

Modèle d'objet CSS

Le modèle d'objet CSS, ou CSSOM, définit les API JavaScript pour travailler avec le CSS. Vous trouverez ci-dessous la liste des nouvelles API liées aux régions CSS:

  • document.webkitGetNamedFlows(): fonction qui renvoie la collection de flux nommés disponibles dans le document.
  • document.webkitGetNamedFlows().namedItem("article"): fonction qui renvoie une référence à un flux nommé spécifique. L'argument correspond au nom spécifié comme valeur des propriétés CSS flow-into et from-from. Pour obtenir une référence au flux nommé spécifié dans l'extrait de code ci-dessus, vous devez transmettre la chaîne "article".
  • WebKitNamedFlow: représentation d'un objet d'iceberg nommé avec les propriétés et fonctions suivantes :
    • firstEmptyRegionIndex: valeur entière qui pointe vers l'index de la première région vide associée au flux nommé. Consultez getRegions() ci-dessous pour savoir comment obtenir la collection de régions.
    • name: valeur de chaîne avec le nom du flux.
    • overset: propriété booléenne qui est :
      • false lorsque le contenu du flux nommé correspond aux régions associées
      • true lorsque le contenu ne tient pas et que d'autres régions sont nécessaires pour le contenir.
    • getContent(): fonction qui renvoie une collection avec des références aux nœuds qui alimentent le flux nommé.
    • getRegions(): fonction qui renvoie une collection avec des références aux régions contenant le contenu du flux nommé.
    • getRegionsByContentNode(node): fonction qui renvoie une référence à la région contenant le nœud spécifié. Cela est particulièrement utile pour trouver des régions contenant des éléments tels que des ancres nommées.
  • Événement webkitregionoversetchange. Cet événement est déclenché sur un WebkitNamedFlow chaque fois que la mise en page du contenu associé change pour une raison quelconque (ajout ou suppression de contenu, modification de la taille de la police, modification de la forme de la région, etc.) et entraîne la modification de la propriété webkitRegionOverset d'une région. Cet événement est utile pour écouter les modifications de mise en page grossières. Il s'agit d'un indicateur indiquant qu'un événement important s'est produit et que la mise en page peut nécessiter une attention particulière (par exemple, si d'autres régions sont requises, si certaines régions sont vides, etc.).
  • Événement webkitregionfragmentchange. Non implémenté au moment de cette modification. Cet événement est déclenché sur un WebkitNamedFlow chaque fois que la mise en page du contenu associé change pour une raison quelconque, comme pour webkitregionoversetchange, mais indépendamment de toute modification des propriétés webkitRegionOverset. Cet événement est utile pour écouter les modifications de mise en page précises qui n'affectent pas nécessairement l'ensemble de la mise en page du flux nommé. Par exemple, le contenu est déplacé d'une région à une autre, mais le contenu global s'adapte toujours à toutes les régions.
  • Element.webkitRegionOverset: les éléments deviennent des régions lorsqu'ils sont associés à la propriété CSS flow-from. Ces éléments disposent d'une propriété webkitRegionOverset qui, s'ils font partie d'un flux nommé, indique si le contenu d'un flux déborde ou non de la région. Les valeurs possibles pour webkitRegionOverset sont les suivantes :
    • "dépassement" si le contenu est supérieur à la capacité de la région
    • "fit" si le contenu s'arrête avant la fin de la région
    • "empty" si le contenu n'a pas atteint la région

L'une des principales utilisations du CSSOM consiste à écouter les événements webkitregionoversetchange et à ajouter ou supprimer dynamiquement des régions afin d'adapter la quantité de texte. Par exemple, si la quantité de texte à mettre en forme est imprévisible (peut-être générée par l'utilisateur), si la fenêtre du navigateur est redimensionnée ou si la taille de la police change, il peut être nécessaire d'ajouter ou de supprimer des régions pour s'adapter au changement de flux. De plus, si vous souhaitez organiser votre contenu en pages, vous aurez besoin d'un mécanisme permettant de modifier dynamiquement le DOM et vos régions.

L'extrait de code JavaScript suivant montre comment utiliser le CSSOM pour ajouter dynamiquement des régions si nécessaire. Notez que, par souci de simplicité, il ne permet pas de supprimer des régions ni de définir leur taille et leur position. Il ne sert qu'à des fins de démonstration.

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.
}

D'autres démonstrations sont disponibles sur la page des exemples de régions CSS.

Modèles de page CSS

L'utilisation du CSSOM est probablement le moyen le plus puissant et le plus flexible d'implémenter des éléments tels que la pagination et la mise en page responsive. Toutefois, Adobe travaille depuis suffisamment longtemps avec des outils de texte et de PAO pour savoir que les concepteurs et les développeurs voudront également disposer d'un moyen plus simple d'obtenir des fonctionnalités de pagination relativement génériques. Nous travaillons donc sur une proposition appelée "Modèles de page CSS", qui permet de définir le comportement de pagination de manière entièrement déclarative.

Examinons un cas d'utilisation courant des modèles de pages CSS. L'extrait de code ci-dessous montre comment utiliser le CSS pour créer deux flux nommés: "article-flow" et "timeline-flow". Il définit également un troisième sélecteur appelé "combined-articles", dans lequel les deux flux seront contenus. L'inclusion simple de la propriété overflow-style dans le sélecteur "combined-articles" indique que le contenu doit être paginé automatiquement le long de l'axe X, ou horizontalement:

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

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

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

Maintenant que les flux ont été définis et que le comportement de débordement souhaité a été spécifié, nous pouvons créer le modèle de page lui-même:

@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; % }
    }
}

Les modèles de page sont définis à l'aide de la nouvelle syntaxe "at". Dans l'extrait de code ci-dessus, nous définissons trois emplacements, chacun correspondant à une colonne. Le texte de "article-flow" s'affichera dans les colonnes de gauche et de droite, et celui de "timeline-flow" dans la colonne du milieu. Le résultat peut ressembler à ceci:

Exemple de modèles de page
Exemple de modèles de pages

Notez que le texte de l'article (dans les colonnes de gauche et de droite) est en anglais, tandis que la chronologie au centre est en allemand. De plus, les pages du document sont affichées horizontalement sans avoir besoin de code JavaScript. Tout a été fait de manière entièrement déclarative en CSS.

Les modèles de page CSS sont encore une proposition, mais nous disposons d'un prototype qui utilise un "shim" JavaScript (également appelé polyfill) pour vous permettre de les tester dès maintenant.

Pour en savoir plus sur les régions CSS en général, consultez la page sur les régions CSS sur html.adobe.com.

Exclusions CSS

Pour obtenir une mise en page semblable à celle d'un magazine, il ne suffit pas de pouvoir faire passer le texte dans les régions. Un élément essentiel de la PAO de haute qualité et visuellement intéressante est la possibilité de faire en sorte que le texte s'écoule autour ou à l'intérieur de graphiques et de formes irrégulières. Les exclusions CSS apportent ce niveau de qualité de production au Web.

La capture d'écran ci-dessous provient d'un prototype d'exclusions CSS. Elle montre un texte qui s'écoule de manière dynamique autour d'un tracé correspondant au contour d'une grande formation rocheuse:

Exemple d&#39;exclusions CSS en action
Exemple d'exclusions CSS en action

L'inverse est illustré dans la capture d'écran suivante: le texte s'écoule à l'intérieur de polygones de forme irrégulière:

Texte s&#39;écoulant dans des polygones de forme irrégulière
Text flowing into irregularly shaped polygons

La première étape pour pouvoir faire passer du texte autour ou à l'intérieur de formes arbitraires consiste à développer et optimiser les algorithmes requis. Adobe travaille actuellement sur des implémentations qui seront directement intégrées à WebKit. Une fois ces algorithmes optimisés, ils constitueront la base sur laquelle le reste des exclusions CSS sera construit.

Pour en savoir plus sur les exclusions CSS, consultez la page sur les exclusions CSS sur html.adobe.com. Pour en savoir plus sur le travail d'Adobe sur la technologie sous-jacente des exclusions CSS, consultez l'article de blog de Hans Muller intitulé Horizontal Box: Polygon Intersection for CSS Exclusions (Cadre horizontal : intersection de polygones pour les exclusions CSS).

État actuel des régions CSS et des exclusions CSS

La première fois que j'ai parlé publiquement des régions CSS et des exclusions CSS, c'était lors du pod Adobe Developer lors de Google I/O 2011. À l'époque, je présentais des démonstrations dans notre propre navigateur de prototype personnalisé. L'accueil a été extrêmement enthousiaste, mais une déception palpable s'est fait sentir lorsque les spectateurs ont découvert qu'aucune des fonctionnalités que je présentais n'était encore disponible dans les principaux navigateurs.

J'ai de nouveau participé à Google I/O cette année (2012), cette fois en tant que présentateur avec mon collègue Vincent Hardy et Alex Danilo de Google (vous pouvez regarder la présentation ici). Un an plus tard, environ 80% de la spécification des régions CSS a été implémentée dans WebKit et est déjà disponible dans la dernière version de Google Chrome (notez que les régions CSS doivent actuellement être activées via chrome://flags). La prise en charge préliminaire des régions CSS est même disponible dans Chrome pour Android:

Régions dans Chrome pour Android
Régions dans Chrome pour Android

De plus, les régions CSS et les exclusions CSS sont implémentées dans la version preview d'Internet Explorer 10 et figurent actuellement dans la feuille de route 2012 de Mozilla pour Firefox. La prochaine version majeure de Safari devrait prendre en charge la majeure partie de la spécification des régions CSS, et les mises à jour ultérieures devraient inclure le reste.

Vous trouverez ci-dessous un calendrier détaillé des progrès réalisés avec les régions CSS et les exclusions CSS depuis notre proposition initiale au W3C en avril 2011:

Progression des régions et des exclusions
Progression de l'exclusion et des régions

Conclusion

Adobe possède une grande expérience du texte, des polices et de la PAO en général grâce à des outils tels qu'InDesign. Bien que le Web soit déjà une plate-forme très puissante pour le texte, nous souhaitons utiliser nos connaissances et notre expérience pour aller encore plus loin dans la présentation du texte. Les régions CSS et les exclusions CSS permettent de structurer sémantiquement le contenu tout en permettant une mise en page semblable à celle d'un magazine, et donc un Web beaucoup plus expressif.