CSS

CSS3 Grid Layout

Article par (Intégrateur du Dimanche, Strasbourg)
Créé le , mis à jour le (46026 lectures)
Tags : css, positionnement, grille, grid, css3

Le module de positionnement "Grid Layout" est une spécification du W3C à l'état de brouillon (Working Draft) dont les premiers jets datent de 2004.

Sa documentation officielle est actuelllement maintenue par quatre contributeurs, dont trois personnes de Microsoft, ainsi que Daniel Glazman, le co-chairman CSS du W3C.

Avertissement La compatibilité de ce module est pour le moins ténue à l'heure actuelle : comme en témoigne l'excellente ressource Can I Use, seul... Internet Explorer 10+ supporte aujourd'hui cette spécification. Mais les autres ténors (Mozilla, Webkit, Opera) sont également intéressés et ne devraient pas tarder à implémenter ce module, au regard des vastes possibilités offertes par ce schéma de positionnement.

Compatibilté navigateurs du module Grid Layout

Navigateurs Versions
Internet Exlorer Internet Explorer 10+

Le positionnement par grille

the grid

Le concept général de Grid Layout (ou "positionnement en grille") est de diviser virtuellement l'espace en zones majeures dans une page ou une application. Concrètement et schématiquement, il s'agira de découper en lignes et en colonnes comme nous le ferions pour un tableau de mise en page.

On y trouve d'ailleurs de nombreuses références d'affichage "tabulaire" avec lignes et colonnes, rowspan et colspan. En cela, ce schéma de positionnement est très similaire aux tableaux HTML ou aux rendus de type display: table, display: table-cell et autre display: table-row.

Mais la différence la plus flagrante est que la grille consiste en une construction de l'esprit et ne nécessite aucun élément HTML ni balisage pour être élaborée. Aucune charpente physique telle que <table>, <tbody>, <tr>, <td> ou <th> n'est nécessaire, ce qui en facilite l'adaptation à différentes tailles d'écrans et de périphériques : inutile d'intervenir sur l'ordre, la nature ou la "sémantique" des éléments HTML, il suffit de modifier le canevas initial pour qu'ils s'y adaptent.

Les propriétés usuelles de Grid Layout

Propriété Détails
grid, inline-grid déclaration d'un contexte de grille
grid-template déclaration d'un "canevas" de cellules nommées (optionnel)
grid-rows, grid-columns déclaration des dimensions de lignes et colonnes
grid-row, grid-column placement d'un élément dans une ligne ou une colonne
grid-cell positionnement d'un élément au sein d'une cellule nommée
grid-row-span, grid-column-span distribution sur plusieurs lignes ou colonnes
grid-row-align, grid-column-align alignement horizontal ou vertical
grid-layer niveau du plan pour éléments superposés

Mise en oeuvre

On crée un "contexte de grille" tout simplement en appliquant la déclaration display: grid à un élément conteneur qui constituera la trame générale. Cette trame sera définie par un schéma virtuel formé de lignes et colonnes définissant des "cellules".

Tous les enfants (directs) de ce conteneur général, sous réserve qu'ils soient originellement de type "block", seront automatiquement affectés par ce contexte particulier et pourront se placer au sein des "cellules" (grid-cell) de la trame.

Exemple 1 (affichage de deux blocs sur une ligne) :

<body>
   <nav>nav</nav>
    <section>section</section>
</body>
body {
    display: grid;
    grid-columns: 250px 300px;
}
nav {
    grid-column: 1; /* placement en colonne 1 */
}
section {
    grid-column: 2; /* placement en colonne 2 */
}

Grille simple

Démonstration

Note compatibilité : le module "Grid Layout", encore en brouillon (Working Draft), ne fonctionne actuellement que sur IE10 et nécessite des préfixes vendeurs -ms- pour être appliqué (par exemple : display: -ms-grid, ou -ms-grid-row: 2). Sur cette page, nous ne mentionnons que la syntaxe finalisée sans préfixe, mais vous devrez les ajouter pour vos tests.

Exemple 2 (grille de 4 emplacements) :

<body>
    <nav>nav</nav>
    <section>section</section>
    <article>article</article>
    <aside>aside</aside>
</body>
body {
    display: grid;
    grid-columns: 250px 400px;
    grid-rows: 100px 300px;
}
nav {
    grid-column: 1; grid-row: 1;
}
section {
    grid-column: 2; grid-row: 1;
}
article {
    grid-column: 1; grid-row: 2;
}
aside {
    grid-column: 2; grid-row: 2;
}

Grille de 4 emplacements

Démonstration

Variante : la syntaxe de templates

Grid Layout autorise la visualisation sous forme de canevas, en nommant explicitement les emplacement de la grille à l'aide de lettres de l'alphabet.

Avertissement Cette variante n'est actuellement reconnue par aucun navigateur, c'est pourquoi les tests demeurent ardus à réaliser, mais en voici le concept général :

Exemple 3 (template) :

#inGrid {
    display: grid;
    grid-template: "hh"
                   "nc"
                   "ff";
}
#inGrid nav {
    grid-cell: "n"; /* placement de <nav> dans l'emplacement "n" */
}

Les unités de largeur et hauteur

Le modèle d'affichage en grille ne se contente pas d'employer les unités de largeur et hauteur habituelles; il introduit des fonctions complexes permettant de s'adapter à des contextes de contenus différents :

Unité Détails
px, %, em, ex, rem,… pixels, pourcentages, em,… (unités courantes)
fr fraction(s) de l'espace restant
min-content se rapporte à la largeur (ou hauteur) de l'élément le plus petit
max-content se rapporte à la largeur (ou hauteur) de l'élément le plus grand
minmax(min, max) exemple minmax(min-content, 20%) correspond à largeur 20% (ou hauteur), mais au minimum largeur (ou hauteur) du contenu
auto s'adapte à la largeur (ou hauteur) du contenu
fit-content identique à auto et aussi à minmax(min-content, max-content)

Exemple 4 (illustration de l'unité "fr") :

html, body {height: 100%;}
body {
    display: grid;
    grid-columns: 250px 1fr; /* largeur 250px et "espace restant" */
    grid-rows: 100px 1fr;
}
nav {
    grid-column: 1; grid-row: 1;
}
section {
    grid-column: 2; grid-row: 1;
}
article {
    grid-column: 1; grid-row: 2;
}
aside {
    grid-column: 2; grid-row: 2;
}

Démonstration

Centrer les éléments

Grid Layout permet d'aligner les contenus verticalement ou horizontalement à l'aide des propriétés grid-row-align et grid-column-align dont les valeurs peuvent être les suivantes :

Valeur Détails
start aligne l'élément au début de la cellule (gauche ou droite selon le sens de la lecture)
end aligne l'élément à la fin de la cellule (gauche ou droite selon le sens de la lecture)
center place l'élément au centre de la cellule
stretch étire l'élément (ses marges) pour occuper tout l'espace dans la cellule

Exemple 5 (multiples centrages) :

html, body {height: 100%;}
body {
    display: grid;
    grid-columns: 250px 250px;
    grid-rows: 250px 250px;
}
nav {
    grid-column: 1; grid-row: 1;
}
section {
    grid-column: 2; grid-row: 1;
    grid-row-align : center;
}
article {
    grid-column: 1; grid-row: 2;
    grid-column-align : center;
}
aside {
    grid-column: 2; grid-row: 2;
    grid-row-align : center;
    grid-column-align : center;
}

 

centrage

Démonstration

Occuper plusieurs emplacements

Tels les célèbres attributs rowspan et colspan dédiés aux tableaux HTML, le module Grid Layout introduit la possibilité à un élément de s'étaler sur plusieurs emplacements, à la fois horizontalement et verticalement.

Les propriétés CSS grid-row-span et grid-column-span sont chargées d'organiser cette distribution sur plusieurs lignes ou colonnes.

Exemple 6 (column span) :

header {
	grid-column: 1; grid-row: 1;
	grid-column-span: 2;
}
nav {
	grid-column: 1; grid-row: 2;
}
section {
	grid-column: 2; grid-row: 2;
}

template

Démonstration

Le pseudo-élément ::grid-cell

Le pseudo-élément ::grid-cell offre la faculté de nommer un emplacement de la grille de manière très intuitive afin d'y placer un élément.

Avertissement Ce pseudo-élément n'est encore supporté par aucun navigateur.

Exemple 7 (cellules nommées) :

body {
    display: grid;
    grid-columns: 300px 300px;
    grid-rows: 200px 300px;
}
body::grid-cell("nav") { /* la position "nav" sera en 1ère colonne, 2ième ligne */
    grid-column: 1; grid-row: 2;
}
body nav {
    grid-cell: "nav"; /* on se positionne dans "nav" */
}

Les motifs de répétition

Une fonctionnalité particulièrement intéressante du positionnement sous forme de grilles est de pouvoir appliquer des motifs de répétition de colonnes ou de lignes (appelés "patterns").

Par exemple, si je souhaite répéter le motif de colonnes (50px 1em) dix fois dans la grille, j'écrirai grid-columns: (50px 1em)[10]

Exemple 9 (patterns) :

body {grid-columns: 10px (1fr 10px)[4];}
/* correspond à 10px 1fr 10px 1fr 10px 1fr 10px 1fr 10px */

 

répétitions

Démonstration

Vous avez dit "responsive" ?

Pour finir cette présentation du modèle de positionnement Grid Layout en apothéose, j'ai gardé le meilleur pour la fin.

L'un des avantages les plus flagrants d'une grille virtuelle, indépendante des éléments HTML qui peuvent s'y placer, est qu'il est extrêmement aisé de modifier la grille selon le contexte. Par exemple, pour s'adapter immédiatement aux différentes tailles d'écran, il suffit de... changer la grille initiale.

Associé aux CSS3 Media Queries, le modèle de positionnement en grille donne toute sa puissance, plus particulièrement si vous avez opté pour une trame sous forme de variante "template". En effet, seul le patron de départ nécessite d'être modifié : inutile d'intervenir sur la structure HTML, ni même sur le positionnement de chaque élément de page.

Exemple 10 (adaptation aux petits écrans) :

body {
    display: grid;
    grid-template: "abcd";
}


@media (max-width: 640px) {
	body {
		display: grid;
		grid-template: "a"
					   "b"
					   "c"
					   "d";
	}
}

 

responsive

Démonstration

Conclusion et usage

Vu la compatibilité navigateurs quasi inexistante du module Grid Layout, il est bien entendu utopique d'employer ce type de positionnement en production à l'heure actuelle, même sur des périphériques avant-gardistes. Cependant, la simplicité et la robustesse de ce schéma lui promet un bel avenir : Microsoft a ouvert la voie (mais il faudra attendre de passer à Windows 8), et les autres navigateurs vont sans nul doute lui emboîter le pas rapidement.

Rendez-vous dans quelques années ? :)

Pour aller plus loin sur ce sujet, je vous invite à consulter un exposé (PDF) que j'ai présenté le 8 février 2012 lors du cycle de conférences MS TechDays,  concernant le module Grid Layout ainsi que deux autres avancées CSS3.

Ressources

Commentaires

Luleen a dit le

Ca serait extra que ce soit supporté par tous les navigateurs !
Ca faciliterait tellement de choses lol

glow a dit le

Bel article Raphael. Vivement l'implémentation plus généralisée des grid layout !

pchlj a dit le

Et avant d'en arriver là... si déjà ça :

display: table, display: table-cell et autre display: table-row.

c'était supporté !!! ça serait vraiment génial !!

Raphael a dit le

@pchlj : "table-*" (CSS2) est supporté depuis pas mal de temps. Seuls IE6 et IE7 ne le supportent pas ;)

oh!rocks a dit le

Pour une fois, Microsoft est en avance sur tout le monde... :D

chris_tofe a dit le

@oh!rocks : C'est pas faux! :) Pas contre, avant d'être en avance, il faudrait qu'il pense déjà à rattraper les nombreuses années de retard qu'il a face à la concurrence. Mais bon, il faut reconnaître que depuis IE9, Microsoft travaille dans le bon sens, même si tout n'est pas encore parfait!

kustolovic a dit le

Merci pour ces infos. ça fait rêver. reste plus qu'à trouver un moyen de simuler le principe des blocs liés (en PAO) et tout sera parfait^^.

Raphael a dit le

@kustolovic : ça existe déjà (en brouillon forcément) et ça s'appelle CSS3 Regions -> http://dev.w3.org/csswg/css3-regions/ ;)

Manumanu a dit le

@chris_tofe : Même depuis IE8 ; cette version n'avait rien à se reprocher. Ce qui lui a été reproché était le non support des nouvelles propriétés CSS3 et du html5, qui n'étaient à l'époque que des ébauches. Microsoft avait choisit de ne pas implémenter de propriétés expérimentales à base de -ms-, préférant se conformer aux standards actuels. Et alors qu'on leur avait toujours reproché de ne pas respecter les standards, il leur a été reproché de ne pas faire dans l'expérimental :)

Du reste, certaines propriétés nouvellement intégrées dans le CSS3, sont en réalité existantes depuis Internet Explorer 5... Comme quoi, être hors des standards, ça peut aussi apporter du bon un jour.

kustolovic a dit le

@raphael
*verse une larme
merci de l'info, je surveillerai cela de près!

@manumanu: ie8, certaines pseudo-classes css 2 non prises en comptes, certaines propriétés pas tout à fait conforme. Ils auraient pu faire un effort sur des "expérimentales" comme opacity.