Chez Jérémie

Chez Jérémie, parfois c'est sérieux, parfois non !

CSS 3 : Le module "Template Layout"

- Web - Lien permanent

Le future norme CSS3 est composée de modules qui sont normalisés plus ou moins indépendamment. Parmi eux, il y en un, discret, mais qui représente quasiment le sain Graal de la mise en page en CSS : le module "Template Layout". Eric Mayer s'est récement fait la voix des Web Designer afin d'insister sur le besoins que représente un système de mise en page totalement indépendant du flux de la source HTML. Ok, ce module n'est encore implémenté par aucun navigateur, quoi que... mais voyons ce que cela pourrait apporter.

Avoir un système de mise en page qui permettrai de s'affranchir du flux de la source HTML... le rêve de tout les Web Designer. Aujourd'hui ce rêve est à porter de main, grâce au module "Template Layout" de CSS 3. Pas de fausse joie, à ce jour ce module est jeune (seulement 2 itérations en "Working Draft" dont la première date de 2005) et aucun constructeur de navigateur n'envisage de l'implémenter pour le moment, même à titre expérimental.

Comment ça marche ?

Dans sa forme la plus basique, le système de gabarit proposé par ce module repose sur l'utilisation de deux propriétés CSS existantes : display et position.

display va permettre de définir la grille de positionnement. La technique mise en œuvre ressemble à de l'ASCII Art puisqu'on utilise des lettres réparties sur plusieurs lignes pour définir le gabarit. Chaque lettre du gabarit définie une zone ("Slot" en anglais) dans lequel on pourra placer n'importe quel élément HTML.

Par exemple, un gabarit classique (1 en-tête, 2 colones et 1 pied de page) peut être représenté de la manière suivante1 :

body{
    display : "aa"
"bc"
"dd";
}

C'est la propriété position qui nous permettra d'assigner un élément HTML à un des emplacements. Pour cela, il suffit d'utiliser la lettre représentant la zone désirée comme valeur de la propriété position.

Concrètement, cela se matérialisera de la manière suivante :

#header { position : a ; }
#footer { position : d ; }
#content{ position : b ; }
#sidebar{ position : c ; }

Mouais, mais en quoi c'est vraiment détaché de ma structure HTML ?

Imaginons que vous ayez un élément h2 dans votre partie #content, mais que vous vouliez que celui ci soit visuellement placé dans la zone d'en-tête. Avec les techniques actuelles (floating, positionnement absolu, etc), c'est un vrai casse-tête qui n'a pas de solution élégante. Avec cette nouvelle technique il suffit de rajouter la règle suivante :

#content > h2 { position : a ; }

De cette manière votre élément h2 va se placer dans la zone d'en-tête ou il se comportera exactement comme s'il était un élément enfant de cette zone. Les différents éléments placés dans cette zone s'y empileront dans l'ordre natif du flux HTML.

Mais cette zone, elle est virtuelle, comment je fait pour la styliser ?

Et oui, dans notre exemple, les élément #header et h2 font tout les deux partie de la zone d'en-tête, mais ne sont pas relier au niveau du flux HTML, ou si peu (il ne sont pas enfant d'un même élément qui représente cet en-tête). Bref, structurellement parlant, ils n'ont rien en commun. Cependant, il est tout de même possible de faire "comme si". En effet, pour styliser cette zone d'en-tête virtuel, on peut utiliser le pseudo-élément ::slot()

Ainsi, si je veux que ma zone d'en-tête ait un arrière plan rose, il suffit de faire :

body::slot(a){
background : #FCC;
}

Malheureusement, à partir de là, je trouve que la spécification est mal fichue. En effet, les styles applicables au pseudo élément ::slot() sont très restreints. On ne peux modifier que les propriétés d'arrière plan, la propriété vertical-align et la propriété overflow. En l'état, il est impossible de modifier les bordures (iiirk !) ou d'appliquer les règles de colonages (mmmh ?) ni même de fixer... la hauteur et la largeur (huuu ?).

Quoi ! On ne peut pas spécifier la taille des zones du gabarit ?

En fait, si, on peut spécifier la hauteur et la largeur des zones du gabarit mais pas via le pseudo élément ::slot(). De mon point de vue, je trouve ça contre intuitif et en désaccord avec les habitudes déjà connu qu'on peut avoir des CSS. En effet, les largeurs et hauteurs des zones ne sont pas spécifiées à l'aide des propriétés width et height, mais directement via la propriété display. Oui, oui, vous avez bien lu : "via la propriété display" !

Ainsi dans notre exemple, si l'on veut avoir un en-tête d'une hauteur de 100px, un corps d'une hauteur qui s'ajuste en fonction du flux et un pied de page d'une hauteur de 2em, il suffit de spécifier les hauteurs voulu après la déclaration de chaque ligne du gabarit. Ce qui donnera (notez la présence du symbole /) :

body{
    display : "aa" /100px
"bc"
"dd" /2em;
}

Et si on veut spécifier une largeur automatique pour la colonne de contenu principal et en même temps une largeur fixe de 150px pour la colonne de droite me diriez vous ? Et bien pour cela, il suffit de spécifier vos largeurs à la fin de votre déclaration display dans l'ordre des colonnes de votre gabarit de la manière suivante2 :

body{
    display : "a a" /100px
"b c"
"d d" /2em
* 150px;
}

Notez l'utilisation du caractère * pour spécifier une largeur qui doit être calculée automatiquement en fonction de l'espace disponible pour cette colonne. Il est également possible de spécifier des largeurs minimum et maximum pour les gabarit fluide, mais je ne vous assomme pas avec ça car je suis près à parier que cela va évoluer (par exemple, il n'est pas possible de spécifier des hauteurs minimum et maximum pour le moment !!!)

Et au fait, pour les bordure on fait comment ?

Comme je vous le disais précédement, il est impossible de spécifier une bordure pour une zone (ni même un padding ou un margin), et de mon point de vu, c'est un très gros manque pour ce module. Ceci dit, il est éventuellement possible de tricher en créant des zones vides ou des espaces entre ces zones. Pour cela vous pouvez utiliser le symbole .

Par exemple, on peut simplement centrer un gabarit de cette manière :

body{
    display : ". a a ." /100px
". b c ."
". d d ." /2em
* 50% 150px *;
}

Tout cela reste malheureusement un peu insatisfaisant et je soupçonne des raisons liées à la difficulté de maitre en œuvre ce module. Ceci dit, cela évoluera sans doute très vite dès que les première implémentation verront le jour.

Ok, c'est cool, mais on ne peut pas s'en servir ! Non ?

Effectivement, aucun navigateur n'implémente nativement cette fonctionnalité à ce jour. Néanmoins, il existe une implémentation en Javascript sous la forme d'un plugin jQuery (développé par Alexis Deveria) qui ouvre cette fonctionnalité à tout les navigateurs (allez jeter un coup d'œil aux demos, c'est bluffant). Alors oui, vous pouvez commencer à jouer avec les possibilité de ce module.

Néanmoins, temps que ce module ne sera pas plus stable, je vous invite à ne pas en faire usage dans un environnement de production industriel, ou alors avec parcimonie. C'est encore hautement expérimentale.

Mais franchement... ça déchire grave ! :-D


  1. la présentation sur plusieurs ligne est là pour simplifier la lecture du gabarit, mais il est tout à fait possible de tout mettre sur une seul ligne
  2. les espaces surnuméraires n'ont aucune influence sur le gabarit, il sont là pour simplifier la lecture