Niveau : Expert

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.

Tutoriel par (Interaction Designer, La Bruyère)
Créé le , mis à jour le (283639 lectures)
Tags : css, position, positionnement, table, display, table-cell, run-in, compact, inline-block, css3

Sommaire


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-cell;
  width:130px;
  padding: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-cell;
  width:150px;
  padding:25px;
}
.colonne:first-child {
  background:#e6e2af;
}
.colonne + .colonne {
  border-left:2px solid #fff;
  background:#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 (cf. méthode des colonnes factices)
  • 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, Internet Explorer 7 n'implémente pas ce dispositif, ce qui rend naturellement son utilisation périlleuse pour ceux qui souhaitent également supporter cette ancienne version.