INFOS-AREA
  Mise en page CSS avancée grâce à la propriété display
 

La spécification CSS 2.1 met à notre disposition de puissantes possibilités de gestion des surfaces grâce à la propriété display dont certaines des facettes — pourtant séduisantes — continuent à être ignorées.
L'implémentation tardive, voire totalement absente, de ces fonctions dans les UA actuels joue naturellement un rôle prédominant dans la méconnaissance de cette propriété. Faisons un instant abstraction des limitations techniques actuelles pour explorer quelques-unes des possibilités intéressantes du display.

 

Sommaire


      1.Parce que les tableaux avaient du bon…
       2. Le meilleur des deux mondes
       3. Un comportement intelligent tiré d'un frère adjacent
       4. Quid d'une utilisation actuelle?
  1.  

Parce que les tableaux avaient du bon…

L'abandon par de plus en plus d'intégrateurs de l'utilisation de tableaux pour l'élaboration de mises en page a indiscutablement apporté de nombreux avantages, mais également son lot d'inconvénients. Parmi ceux-ci, un majeur: le centrage vertical simple et automatisé du contenu d'un objet.

Les habitudes de plusieurs années de développement par tables ont laissé des traces, des habitudes ancrées de manière indélébile qui ne sont pas systématiquement préjudiciables; c'est entre autres le cas du recours à la propriété vertical-align.

Fort de ce constat, et vu la puissance qu'offre les cellules de tableaux en terme d'alignement vertical de leurs contenus, la spécification CSS admet logiquement l'attribution de ce comportement à tout élément qui en nécessiterait.

Prenons un exemple simple de disposition d'un texte scindé en trois paragraphes que l'on souhaite agencer en drapeau:

Logiquement, ma structure HTML sera des plus simplistes:

<p>Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmod tempor 
incididunt ut labore et dolore magna aliqua.</p> 
 
<p>Ut enim ad minim veniam exercitation, quis nostrud nisi in exercitation 
ullamco laboris nisi sedo ut aliquip in dis ex ea commodo consecis. Duis sed aute irure 
elit sed tempor in reprehenderit in uti voluptate velit esse cillum dolore se eu fugiat 
in sed nulla pariatur cupidatatis.</p> 
 
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia 
deserunt mollit anim id est laborum.</p>

Si le procédé permettant d'aboutir à ce résultat apparaît comme évident dans le cas de l'utilisation d'un tableau, il peut au contraire sembler difficile d'y parvenir sur base de notre marquage HTML. Il suffit pourtant de traiter nos paragraphes comme des cellules de tableau pour concilier la facilité d'emploi de ces derniers à un soucis légitime de sémantique adéquate:

p {display:table-cellwidth:130pxpadding:10px
     
:first-child {text-align:right
:first-child + p {text-align:justify
p+p+p {vertical-align:bottom}

Au-delà de la possibilité d'usage du vertical-align que nous autorise l'attribution d'un display:table-cell à nos éléments, nous observons un comportement attrayant: les éléments adjacents traités comme des cellules de tableau dépendent directement les uns des autres et occupent par conséquent une hauteur équivalente à la plus importante du groupe. Partant de ce principe, il peut être intéressant d'utiliser un tel concept pour créer un squelette de mise en page: la partie centrale disposerait de deux colonnes de contenu dont les couleurs de fond respectives pourraient harmoniser les hauteurs et ce, sans devoir sortir le moindre élément du flux! Voyons un résultat possible:

Schéma de 2 colonnes de même hauteur de quantités de contenu différentes

En pratique, nous pourrions partir de deux divisions disposant d'une même classe colonne qu'on pourrait styler de la manière suivante:

.colonne {display:table-cellwidth:150pxpadding:25px
.colonne:first-child {background:#e6e2af
.colonne + .colonne {border-left:2px solid #fffbackground:#efecca}

Pour information, la pseudo-classe :first-child ciblant notre première colonne ainsi que le sélecteur d'enfants adjacents ciblant la seconde division ne sont pas supportés par Internet Explorer 6.

Si un contenu de flux précède nos deux colonnes, ce qui sera le cas la plupart du temps, il pourra être nécessaire d'englober nos deux "cellules de tableau" dans un parent faisant office de tableau, une division par exemple:

div {display:table}

Notre division étant assimilée à un tableau, nous avons accès aux différentes propriétés qui s'y rattachent, dont border-spacing pour scinder nos cellules.

La possibilité de simuler la mise en forme d'un tableau ne doit bien évidemment être envisagée que dans le cas où l'on souhaite tirer parti de ses bénéfices visuels et non pour substituer l'utilisation de l'élément table par d'autres balises non adaptées sémantiquement. Rappelons que table est un élément HTML parfaitement sain, valide et "sémantique" et qu'il n'y a aucune raison valable de s'en passer pour baliser des données tabulaires.

Cette méthode présente de nombreux avantages de conception et de maintenance en comparaison à d'autres dispositifs homologues, dont:

  • la possibilité de changer à tout moment les couleurs de fonds sans passer par la création d'images
  • le confort de ne pas avoir à prévoir la colonne qui disposera du contenu occupant le plus de hauteur, à l'inverse de l'utilisation de positionnements absolus
  • l'utilisation adéquate d'une propriété dans un but qui lui sied, contrairement aux détournements récurrents de certaines propriétés et au balisage de mise en forme

Malheureusement, la septième version du butineur de Microsoft n'implémente toujours pas ce dispositif, ce qui rend naturellement son utilisation périlleuse à l'heure actuelle.

Le meilleur des deux mondes

Si deux valeurs de display semblent aujourd'hui bien ancrées dans les mœurs des intégrateurs web, ce sont incontestablement inline et block. La valeur hybride inline-block, pourtant diablement efficace, s'illustre quant à elle par une discrétion notoire.

Les éléments nativement en ligne tels que a ou strong — ou dont l'affichage inline a été explicitement spécifié — présentent ce caractère bien souvent recherché de positionnement en succession côte à côte. Ils cantonnent cependant l'élément à occuper, par la même occasion, la place que demande son contenu, conséquence rarement recherchée — par exemple, dans la mise en place d'une grille de mise en page.

La valeur inline-block intervient brillamment à ce niveau-là en permettant de bénéficier à la fois de l'élément en tant que bloc — et par la même occasion de pouvoir spécifier une taille — ainsi qu'en tant qu'élément en ligne au niveau de la gestion des placements.

Ce comportement hétéroclite adopte par la même occasion une gestion singulière des alignements verticaux caractérisée par:

  • un déploiement par défaut du contenu depuis un socle inférieur commun déterminé par l'élément inline-block le plus fourni en contenu ou, de manière plus générale, dont la hauteur dépasse les objets inline-block adjacents
  • l'usage différent de la propriété vertical-align qui agit non plus sur le contenu de la boîte — comme c'est le cas pour les cellules d'une table — mais sur la boîte elle-même

Le positionnement d'éléments en inline-block s'apparente donc, nous l'avons vu, au placement des images sur une ligne de texte. En intégrant ce principe de positionnement, il devient aisé de réaliser des architectures de blocs jusqu'alors difficilement concevables, telles que celle-ci:

Schéma d'organisation de colonnes en drapeau vertical autour d'un bandeau horizontal

Imaginons qu'il s'agisse d'une discussion autour de dictons célèbres. Des paragraphes viendraient introduire la citation (trois en l'occurrence), suivis d'autant de paragraphes que nécessaires à l'analyse de ce dernier, le tout centré horizontalement. Nous partirons logiquement sur un marquage HTML simple, de type:

<body> 
 
    <p>Paragraphe 1</p> 
    <p>Paragraphe 2</p> 
    <p>Paragraphe 3</p> 
 
    <blockquote> 
        <p>Citation centrale</p> 
    </blockquote> 
 
    <p>Paragraphe 4</p> 
    <p>Paragraphe 5</p> 
    <p>Paragraphe 6</p> 
    <p>Paragraphe 7</p> 
    <p>Paragraphe 8</p> 
 
</body>

La mise en forme, grâce à l'inline-block, se réalisera quant à elle en un tour mains:

body {padding:1.5em 0text-align:center
     
body > p {display:inline-blocktext-align:leftwidth:100pxpadding:10pxbackground:#eee
p+p {margin-left:5px
     
blockquote {background:#333color:#fffpadding:10pxmargin:8px 0
blockquote ~ p {vertical-align:topbackground:#bbb}

Les paragraphes étant maintenant considérés comme des éléments en ligne du point de vue des positionnements, un alignement horizontal traditionnel sur notre élément conteneur body suffira à centrer l'ensemble automatiquement. Le sélecteur d'enfants directs (chevron ">", non implémenté par Internet Explorer 6) évite de sélectionner par mégarde un paragraphe se trouvant hors du champ d'application ciblé, tel que celui se trouvant au sein du bloc de citation. Le sélecteur CSS3 général d'adjacence ("~", non supporté par IE6) permet finalement de redéfinir aisément la règle d'alignement de départ pour tous les paragraphes succédant à notre citation.

Le lecteur attentif aura peut-être remarqué une incohérence dans les tailles des marges attribuées. En effet, l'élément blockquote bénéficie de marges verticales plus importantes que les marges de gauche destinées à séparer les différents paragraphes. Pourtant, les zones blanches entre nos différents blocs semblent visuellement identiques. Effet d'optique? Bien au contraire. Afin de comprendre ce phénomène, commençons par analyser un agrandissement de la marge séparant deux paragraphes:

Marge de 8 pixels entre les différentes colonnes

Étonnamment, nous observons une zone large de huit pixels malgré l'instruction de cinq pixels donnée. Que s'est-il passé? La raison est simple, et parfaitement logique: nos paragraphes étant considérés comme des éléments "normaux" au niveau de leur état dans le flux, ils répondent dès lors aux lois habituelles de cette catégorie et sont sensibles aux espaces blancs indiqués dans notre code HTML par les différents retours à la ligne (voir le post Impact sur le rendu de la mise en forme du code HTML à ce sujet). En juxtaposant nos différentes balises sans espaces, nous supprimons logiquement ces écarts:

<p>Paragraphe 1</p><p>Paragraphe 2</p><p>Paragraphe 3</p>

Si la lisibilité de notre document source pâtit cruellement de ce manque d'aération rendant pénible toute relecture ou maintenance future, nous pourrons recourir à divers artifices relevant, il faut le dire, plus de la bidouille qu'autre chose, mais améliorant sensiblement la clarté du marquage. Parmi ces solutions, citons le recours possible aux commentaires:

<p>Paragraphe 1</p><!-- 
--><p>Paragraphe 2</p><!-- 
--><p>Paragraphe 3</p>

Nous pouvons également écrire notre marquage par le biais d'un langage dynamique, tel que PHP, afin d'éviter ces espaces indésirables:

<?php 
echo '<p>Paragraphe 1</p>'
echo '<p>Paragraphe 2</p>'
echo '<p>Paragraphe 3</p>'
?>

En termes d'implémentations, la valeur inline-block est celle qui s'en sort le mieux, bien qu'elle nécessite toutefois un léger correctif pour pouvoir fonctionner sur Internet Explorer

Un comportement intelligent tiré d'un frère adjacent

La boîte en enfilade est sans conteste la plus mal connue des techniques de mises en forme existantes, et indubitablement la plus mal implémentée à l'heure actuelle puisque seul Presto, le moteur du navigateur Opera, peut prétendre à son support intégral. Elle peut pourtant apporter son quota de commodités qu'on aurait tort de négliger.

La valeur run-in possède la particularité d'attribuer à une boîte un comportement différent selon le type d'objet qui lui succède:

  • si l'élément suivant une boîte en enfilade est de type inline, la boîte en enfilade est rendue sous forme de bloc
  • si l'élément suivant une boîte en enfilade est de type block, la boîte en enfilade est rendue sous forme d'élément en ligne et insérée au début de la boîte block immédiatement adjacente

Prenons le premier cas avec un exemple simple:

<strong>Brièvement…</strong> Lorem ipsum dolor sit amet, 
consectetur adipisicing elit, sed do eiusmod tempor…

Attribuer à notre élément de mise en exergue un comportement de boîte en enfilade résultera logiquement à transformer ce dernier en bloc, permettant par la même occasion d'en tirer les avantages inhérents, dont l'accès aux marges verticales et à l'occupation physique de l'entièreté de la largeur de son parent.

strong {display:run-in; border-bottom:1px solid #ccc; margin-bottom:.8em; padding-bottom:.8em}

L'adoption d'un mode d'affichage précis par la boîte en enfilade selon la structure avoisinante est flagrante lors de la modification d'un marquage antérieur. Dans le cas de notre exemple, englober notre texte de substitution (“Lorem ipsum…”) dans un paragraphe aura pour effet l'insertion à son origine de notre boîte de mise en exergue, désormais de type inline.

Cette ambivalence typique à run-in permet d'anticiper certains traitements automatisés et de prévoir un mode de rendu cohérent en fonction du contexte. D'autre part, certaines orientations graphiques précises demanderaient tantôt la modification d'une structure HTML qui n'aurait à priori pas à être altérée, tantôt un bricolage fragile basé sur le détournement de certaines propriétés. L'exemple suivant illustre l'intégration d'une direction visuelle particulière grâce au système de boîte en enfilade:

Notre structure HTML décrira un titre de second niveau et un paragraphe de contenu:

<h2>Notre société</h2> 
<p>Lorem ipsum dolor sit amet…</p>

En gardant à l'esprit qu'h2 est maintenant un élément inline se trouvant au début de notre paragraphe, la construction du visuel pourra se faire ainsi:

h2 {display:run-in; background:#000; color:#fff; padding:70px 3px 1px; margin-right:5px} 
p {border:1px solid; padding:69px 20px 20px}

Rappelons que c'est la présence d'une boîte de type block — notre paragraphe — succédant à notre titre qui a dicté à ce dernier le comportement a adopter. Le résultat de cette transformation de marquage pourrait s'écrire:

<p> 
    <h2 style="display:inline">Notre société</h2> 
    Lorem ipsum dolor sit amet… 
</p>

Bien entendu, cette écriture invalide et pataude ne sert qu'à visualiser la métamorphose de notre bloc de titre. Notons finalement à des fins pédagogiques que la valeur compact — initiée par CSS2 puis ôtée de CSS2.1 — présentait un comportement passablement similaire.

Quid d'une utilisation actuelle?

Les possibilités d'architecture de mise en page au moyen des fonctionnalités offertes par la propriété display se révèlent tant nombreuses qu'alléchantes d'un point de vue pratique et créatif. Les agents utilisateurs actuels n'offrent malheureusement qu'un bien piètre support de ces différentes facultés d'affichage, puisque:

  • display:table-cell n'est au jour d'aujourd'hui pas supporté par Internet Explorer
  • display:inline-block, implémenté dans Safari & Opera, ne sera supporté dans Firefox qu'à partir de sa troisième version (au stade bêta à l'heure où j'écris ces lignes). Il est néanmoins possible de simuler partiellement son comportement sur les versions actuelles du navigateur de Mozilla grâce à la valeur propriétaire -moz-inline-stack (cf. “Inline-block dans tous les navigateurs modernes?”). Rappelons que la spécification autorise et valide l'utilisation de ce type de valeurs lorsqu'elles sont précédées d'un tiret. Internet Explorer, quant à lui, n'admet la transformation que pour un élément initialement de type inline. Cette restriction peut fort heureusement être levée sans peine en adressant à ce dernier — idéalement par commentaires conditionnels — un correctif pour les éléments visés:
    élément1
    élément2
    élément3 

        zoom:1;     /* Attribution du layout à l'élément */ 
        display:inline    /* Passage de block à élément inline */ 
    }
  • display:run-in est implémenté uniquement par Opera dans sa globalité; Safari supporte quant à lui le cas d'une transformation d'un bloc en élément en ligne mais n'accepte pas l'inverse.

Si seule la valeur inline-block pourra, dans un avenir proche, être décemment envisagée dans les contextes de production réels, il n'en demeure pas moins que la préparation aux autres techniques de mise en forme s'avère essentielle dès maintenant. Il est nécessaire d'appréhender ces différents modes d'affichages au plus tôt et d'adopter un comportement pro-actif à cet égard afin d'assurer une adoption sereine des technologies de mise en forme de demain. Les récentes annonces de Microsoft à propos de la huitième version de son butineur contribuent à nous laisser imaginer de profondes modifications dans nos schémas d'intégration futurs; assurons-nous d'y être bien préparé!


 
  Aujourd'hui sont déjà 7 visiteurs (242 hits) Ici! ;  
 
Ce site web a été créé gratuitement avec Ma-page.fr. Tu veux aussi ton propre site web ?
S'inscrire gratuitement