Créons, ensemble, des sites qui feront le bonheur de vos utilisateurs
(Expérimental)

Résultats trouvés

Commencez à taper quelque chose, la recherche se déclanchera toute seule !

CSS Grid : un contrôle total sur votre mise en page

Comme je l'ai déjà évoqué dans mon précèdent article sur les normes de colonage, de régions et de formes, CSS3 apporte de nombreuses nouveautés pour tenter de mettre fin aux nombreuses bidouilles qui avaient cours jusqu'à présent.

Une de ces norme est CSS Grid qui va permettre de contrôler la manière dont s'agence nos différents blocs dans une page.

Grid ou Flexbox

La norme CSS3 qui prend beaucoup d'ampleur en ce moment est Flexbox. Elle permet d'utiliser un modèle d'affichage beaucoup plus flexible pour décider si nos blocs devront s'afficher en ligne ou en colonne, leurs alignements horizontaux et surtout verticaux, la répartition en fonction de l'espace disponible, l’ordre des blocs, etc.

Si Flexbox est parfaitement adaptée pour agencer des blocs les uns par rapports aux autres, en ligne ou en colonnes, il subsiste une lacune dans cette spécification : comment faire pour mélanger efficacement les lignes et les colonnes sans devoir imbriquer nos flexbox dans des flexbox de flexbox...

C’est souvent le cas pour la mise en page globale d’un site web, par exemple avec un gabarit classique comme celui du site de la BBC :

Page d'accueil de la BBC

Qui pourrait être schématisé sous la forme suivante :

Modélisation de la page d'accueil

Il est bien évidemment possible de faire ce genre de chose sans les grilles CSS puisque la BBC le fait. Cependant la complexité induite est assez importante, surtout si la page doit pouvoir s’adapter aux différentes tailles d’écrans de manière responsive.

Support dans les navigateurs

Cette norme est encore très expérimentale. Elle est supportée que sous IE 10+ avec le préfixe -ms et dans une ancienne syntaxe. Elle est également utilisable sous chrome en activant les fonctionnalités web expérimentales dans chrome://flags.

Le besoin étant définitivement présent, elle arrivera fort probablement assez vite dans la plupart des navigateurs.

La syntaxe de base

La norme étant en cours de spécification, la syntaxe n'est probablement pas définitive. Par exemple, la syntaxe gérant les alignements a changé, pour l'uniformiser avec celle de Flexbox.

Pour utiliser CSS Grid, la première chose à faire est de définir un conteneur auquel on fixe la propriété display à la valeur grid.

display: grid

Une fois cette étape faite, nous allons pouvoir travailler avec des lignes et des colonnes de manière identique à ce qui était fait lorsque la plus part des sites utilisaient les balises table pour leur mise en page mais, ici, de manière plus élégante.

Les propriétés grid-row et grid-column vont nous permettre de placer un élément directement dans la grille. Si l’on prend un exemple simple :

<div class="container">
	<div class="block1">Bloc 1</div>
	<div class="block2">Bloc 2</div>
	<div class="block3">Bloc 3</div>
	<div class="block4">Bloc 4</div>
</div
.container {
	display: grid;
}

.block1 {
	grid-row: 1;
	grid-column: 1;
}

.block2 {
	grid-row: 1;
	grid-column: 2;
}

.block3 {
	grid-row: 2;
	grid-column: 1;
}

.block4 {
	grid-row: 2;
	grid-column: 2;
}

Ce qui nous donne le résultat suivant (après avoir fixé la taille des blocs à 200x200px pour améliorer le rendu) :

Rendu de la grille

Pour que les blocs prennent toute la place disponible, il est possible de définir la taille de chaque ligne et de chaque colonne. Cela se fait sur le bloc conteneur à l’aide des propriétés grid-template-rows et grid-template-columns. Chaque valeur séparée par un espace correspondant à une ligne ou une colonne.

Afin de vous faciliter le travail de nouvelles unités font leur apparition en plus des existantes :

  • fr : fraction de l’espace restant
  • min-content : taille de l'élément le plus petit
  • max-content : taille de l'élément le plus grand
  • fit-content : équivalent de “auto”

Par exemple :

.container {
	display: grid;
	grid-template-columns: 200px 1fr;
	grid-template-rows: 200px 200px;
}

Nous donne :
Rendu de la grille

Note : dans la version implémentée par Microsoft, les propriétés sont remplacées par -ms-grid-columns et -ms-grid-rows.

L'alignement

Suite à l'arrivée de Flexbox et maintenant de Grid, le W3C a unifié la gestion des alignements sous une norme dédiée nommée CSS-Align. Cette norme s'occupe de définir les propriétés pour aligner les éléments horizontalement et verticalement et s'applique à Flexbox, Grid, aux tableaux et aux blocs.

Cette norme est très puissante et permet de définir :

  • l'alignement des blocs individuellement avec les propriétés justify-self et ** align-self**
  • un alignement par défaut sur le conteneur parent avec les propriétés justify-items et align-items
  • la distribution des enfants d'un conteneur avec les propriétés justify-content et align-content

Les noms ne sont pas très explicites car, en CSS, les blocs peuvent s'empiler soit les uns à côtés des autres horizontalement (inline) ou les uns en dessous des autres verticalement (stacking). Les propriétés justify-xxx correspondent donc à l'alignement sur l'axe principal et align-xxx à l'alignement sur l'axe secondaire.

Dans le cas de CSS grid, l'axe principal est horizontal et par conséquent justify-xxx correspond à l'alignement horizontal et align-xxx à l'alignement vertical.

Ainsi, nous avons :

  • justify-self et align-self qui s'appliquent sur un bloc spécifique
  • justify-items et align-items qui s'appliquent à la grille pour définir l'alignement par défaut de tous ses blocs
  • justify-content et align-content qui s'applique à la grille pour définir sa répartition dans son parent

Les valeurs de base acceptées pour l'alignement des blocs sont identiques pour les deux types d'alignement :

  • center : aligne le bloc au milieu de l'axe
  • start : aligne le bloc au début de l'axe (gauche ou haut)
  • end : aligne le bloc à la fin de l'axe (droite ou bas)

Il en existe d'autres fonctionnant différemment en fonction du contexte et que je ne détaille pas dans cet article.

.block1 {
	grid-row: 1;
	grid-column: 1;
	justify-self: center;
	align-self: center;
}

.block2 {
	grid-row: 1;
	grid-column: 2;
	justify-self: end;
	align-self: end;
}

Nous donnera :
Rendu de la grille avec alignements

Notez que les blocs alignés, qui par défaut prenaient toute la place disponible, se réduisent à la taille de leur contenu.

Note : Au moment de la rédaction de l'article l'implémentation de l'alignement sur Chrome est encore assez boguée. La capture d'écran a été faite sous IE en utilisant les propriétés -ms-grid-row-align et -ms-grid-column-align qui fonctionnent de manière similaire mais correspondent à l'ancienne syntaxe.

Chevauchement

Il est également possible de définir des blocs chevauchant plusieurs lignes ou colonnes en modifiant la valeur des propriétés grid-row et grid-column et en lui ajoutant, en plus de la position le nombre de blocs de chevauchement séparée par un / et précédé de span.

Par exemple pour un chevauchement de 4 colonnes vers la droite :

grid-column: 2 / span 4;

Par exemple pour un chevauchement de 4 colonnes vers la gauche :

grid-column: span 4 / 2;

En ajoutant une colonne à notre exemple initial :

.container {
	display: grid;
	grid-template-columns: 200px 1fr 50px; /* on ajoute une colonne de 50px */
	grid-template-rows: 50px 50px;
}

.block4 {
	grid-row: 2;
	grid-column: 2 / span 2;
}

Et nous obtenons :
Rendu de la grille avec un chevauchement

Note, sous IE vous pouvez obtenir le même résultat en utilisant les propriétés -ms-grid-row-span et -ms-grid-column-span.

Et plein d'autres choses...

Si avec les exemples que nous avons vu jusqu'à présent vous pouvez voir que la syntaxe est bien plus légère, en HTML et en CSS, que l'utilisation de tableaux, son avantage principal est sa flexibilité lorsqu'on la couple aux média queries.

Il est ainsi possible de changer l'ordre des blocs avec la propriété order, de définir des sous-grilles, de contrôler très finement l'emplacement de chaque bloque, de répéter une configuration de ligne ou de colonne, de contrôler les lignes et les colonnes générées automatiquement si vous positionnez des éléments en dehors de la grille explicitement définie, etc.

La fonctionnalité la plus impressionnante étant probablement la possibilité d'utiliser des gabarits basés sur le nom.

Cette fonctionnalité nous permet de définir des gabarits de page directement en CSS à l’aide de la propriété grid-template-areas qui permet de dessiner notre page, de nommer chaque cellule et de remplacer l’utilisation de grid-row et de grid-column.

Pour obtenir l’équivalent de notre exemple précédent la syntaxe aurait été :

.container {
	display: grid;
	grid-columns: 200px 1fr 50px;
	grid-rows: 50px 50px;
	grid-template-areas: "bloc1 bloc2 ."
		                 "bloc3 bloc4 bloc4";
}

.block1 {
	grid-area: bloc1;
}

.block2 {
	grid-area: bloc2;
}


.block3 {
	grid-area: bloc3;
}

.block4 {
	grid-area: bloc4;
}

Il faut que chaque ligne de la propriété grid-template-areas ait le même nombre de colonnes. Par conséquent si vous avez une colonne vide, comme c'est le cas pour nous au niveau de la troisième colonne de la première ligne, il suffit de remplacer le nom par un point (.).

Conclusion

Cet article ne fait que survoler la spécification pour vous donner un aperçu des possibilités. Il existe de nombreuses possibilités et il sera intéressant de voir ce qui sera retenu au final par les différents navigateurs une fois que la norme aura été implémentée de manière plus large.

Un système de mise en page flexible et efficace manquait réellement depuis longtemps en CSS. L'arrivée de smartphones et du Responsive Web Design l'a rendu vitale et ce manque est en train d'être comblé progressivement.

Flexbox a été un pas important dans cette direction et avec un peu de chance, CSS Grid arrivera bientôt pour finir de combler ce besoin.

Vous pouvez commencer dès à présent à tester la norme dans Chrome ou dans IE, mais n’oubliez pas qu'elle reste encore très expérimentale et volatile.


## Pour aller plus loin ##

Autour du sujet

Consultez mon article sur les colonnes, régions et shapes en CSS3.

Découvrez la formation HumanCoders sur CSS3 avancé : http://formations.humancoders.com/formations/css3

Ou invitez moi pour un BBL sur les dernières nouveautés HTML5/CSS3 ou sur comment booster vos mises en pages avec CSS3 : http://www.brownbaglunch.fr