Dans ce chapitre, on va découvrir le principe des grilles en CSS. On a déjà vu qu'avec display: flex, on pouvait aligner des éléments selon un axe principal. Avec display: grid, on change d'approche : au lieu de raisonner en ligne ou en colonne, on définit directement une grille prédéfinie dans laquelle les éléments enfant vont venir se placer.
C'est un mode de mise en page particulièrement pratique dès qu'on veut organiser un contenu en plusieurs colonnes, créer une structure de page plus complexe ou construire des blocs qui se réorganisent facilement.
Le principe de display: grid
Comme pour les flexbox, on travaille toujours avec un parent qui englobe plusieurs enfants.
.demo {
display: grid;
}
À partir du moment où un élément passe en grid, ses enfants peuvent être positionnés dans des colonnes et des lignes.
Par défaut, on ne voit pas forcément de changement particulier car ce positionnement va créer une seule colonne et chaque enfant occupe une seule ligne.
Définir les colonnes avec grid-template-columns
La première propriété importante est :
grid-template-columns
Elle permet de définir la taille des colonnes de la grille.
.demo {
display: grid;
grid-template-columns: 100px 100px 100px;
}
Ici, on crée trois colonnes de 100px.
Cette popriété permet de piloter précisément la structure horizontale de la grille, ce qui est l'un des grands avantages de ce mode de disposition.
Définir les lignes avec grid-template-rows
On peut faire la même chose pour les lignes :
.demo {
display: grid;
grid-template-rows: 50px 100px 50px;
}
Ici, on crée trois lignes avec des hauteurs différentes.
Et si on a plus d'enfants que ce qui est prévu par la grille, le navigateur crée automatiquement des lignes supplémentaires.
L'espacement avec gap
Comme pour flexbox, on peut créer de l'espace entre les lignes et les colonnes avec :
gap: 20px;
Ou avec les propriétés plus spécifiques :
row-gap: 10px;
column-gap: 20px;
La propriété gap fonctionne donc aussi très bien avec les grilles.
justify-content et align-content
Si la grille n'occupe pas toute la largeur ou toute la hauteur du conteneur, on peut contrôler sa position à l'intérieur du parent.
.demo {
display: grid;
justify-content: center;
align-content: center;
}
Ces propriétés permettent d'aligner la grille elle-même :
justify-contentagit horizontalementalign-contentagit verticalement
Le mot-clé important ici, c'est bien content : on parle de la grille dans son ensemble.
justify-items et align-items
À l'inverse, si on veut contrôler la position des éléments dans chaque case de la grille, on utilise :
.demo {
display: grid;
justify-items: center;
align-items: center;
}
Cette fois :
justify-itemsaligne les éléments horizontalement dans leur cellulealign-itemsaligne les éléments verticalement dans leur cellule
Il est important de bien distinguer les deux niveaux :
contentagit sur la grille dans son ensembleitemsagit sur les éléments à l'intérieur de chaque case
Les raccourcis place-content et place-items
CSS propose aussi deux raccourcis pratiques :
place-content: center;
place-items: center;
Ils regroupent respectivement :
align-content+justify-contentalign-items+justify-items
Ce n'est pas indispensable, mais c'est utile à connaître.
Les fractions avec fr
Quand on veut répartir l'espace disponible, on peut utiliser une unité spécifique aux grilles : fr, pour fraction.
.demo {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
Cela signifie que l'espace disponible est divisé en trois parts égales, une pour chaque colonne.
L'intérêt de fr, c'est qu'il prend en compte l'espace restant, contrairement aux pourcentages qui peuvent rapidement provoquer des débordements si on ajoute aussi du gap.
Par exemple :
grid-template-columns: 1fr 2fr 1fr;
Dans ce cas, la colonne centrale prendra deux fois plus d'espace que les deux autres.
On peut aussi mélanger des tailles fixes et des fractions :
grid-template-columns: 200px 1fr;
Ici, la première colonne fera 200px, et la seconde prendra tout l'espace restant.
repeat()
Quand on veut répéter plusieurs fois la même taille de colonne ou de ligne, la fonction repeat() évite de dupliquer la même valeur.
grid-template-columns: repeat(5, 1fr);
Cette écriture revient à faire :
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
C'est particulièrement utile quand on veut construire des grilles régulières.
Les propriétés appliquées aux enfants
Comme avec flexbox, les enfants d'une grille peuvent eux aussi recevoir des propriétés particulières.
justify-self et align-self
Ces propriétés permettent de changer l'alignement d'un élément spécifique à l'intérieur de sa cellule.
.item {
justify-self: start;
align-self: start;
}
Elles jouent donc le même rôle que justify-items et align-items, mais cette fois au niveau d'un seul enfant.
grid-row et grid-column
L'un des grands intérêts de Grid, c'est qu'on peut dire à un élément dans quelle ligne ou quelle colonne il doit se placer.
Par exemple :
.item {
grid-row-start: 2;
grid-row-end: 4;
}
Ici, l'élément commence à la ligne 2 et s'arrête avant la ligne 4.
Même logique pour les colonnes :
.item {
grid-column-start: 2;
grid-column-end: 5;
}
Cela permet à l'élément d'occuper plusieurs colonnes.
La syntaxe raccourcie
On peut écrire la même chose plus simplement :
grid-row: 2 / 4;
grid-column: 2 / 5;
Cette écriture est très courante en pratique.
Les valeurs négatives
Dans Grid, on peut utiliser des valeurs négatives pour compter depuis la fin.
grid-column: 1 / -1;
Cela signifie que l'élément commence à la première colonne et s'étend jusqu'à la dernière ligne de séparation disponible.
C'est très pratique pour faire occuper à un élément toute la largeur d'une grille, par exemple pour un header ou un footer.
Le mot-clé span
Au lieu de préciser une ligne ou une colonne de fin, on peut aussi dire combien de colonnes ou de lignes l'élément doit occuper.
grid-column: 1 / span 2;
Ici, l'élément démarre à la colonne 1 et s'étend sur deux colonnes.
Cette syntaxe est souvent plus intuitive quand on veut simplement dire "cet élément doit prendre deux cases".
Un point de vigilance
Comme avec order dans flexbox, déplacer visuellement des éléments avec Grid ne change pas l'ordre HTML.
Cela peut provoquer des comportements un peu surprenants, notamment lors :
- de la sélection de texte
- de la navigation clavier
- de certains usages liés à l'accessibilité
En pratique, on utilisera surtout grid-row et grid-column pour faire occuper plus ou moins d'espace à un élément, plutôt que pour réorganiser complètement l'ordre visuel d'une interface.
grid-auto-flow
Par défaut, les éléments d'une grille se placent ligne par ligne. C'est le comportement de :
grid-auto-flow: row;
Mais on peut changer cela :
grid-auto-flow: column;
Dans ce cas, les éléments remplissent d'abord les colonnes.
On peut aussi utiliser le mot-clé dense :
grid-auto-flow: row dense;
Le navigateur va alors essayer de combler les trous laissés dans la grille en réutilisant des éléments capables de rentrer dans les cases restantes.
Cela peut être utile dans certaines dispositions irrégulières, même si ce n'est pas le cas le plus courant.
grid-template-areas
Quand une grille devient un peu plus complexe, manipuler les numéros de lignes et de colonnes peut devenir difficile à lire.
Dans ce cas, grid-template-areas est une très bonne solution.
Le principe consiste à donner des noms aux zones de la grille :
.layout {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
On définit ici visuellement une structure en deux colonnes et trois lignes :
- le header prend toute la largeur
- la sidebar est à gauche
- le contenu principal est à droite
- le footer prend toute la largeur
Ensuite, au niveau des enfants, on assigne chaque élément à sa zone :
.header {
grid-area: header;
}
.sidebar {
grid-area: sidebar;
}
.main {
grid-area: main;
}
.footer {
grid-area: footer;
}
L'intérêt de cette approche, c'est qu'on peut changer la structure de la page directement depuis le parent, sans toucher à tous les enfants.
Cela rend les mises en page complexes beaucoup plus lisibles.
Les grilles responsives avec auto-fill, auto-fit et minmax()
L'un des usages les plus intéressants de Grid apparaît quand on veut créer une grille qui s'adapte automatiquement à la largeur disponible.
On peut utiliser pour cela :
grid-template-columns: repeat(auto-fill, 100px);
Le navigateur crée alors autant de colonnes qu'il peut de 100px.
Mais on peut aller plus loin avec minmax() :
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
Cela signifie :
- chaque colonne doit faire au minimum
100px - et au maximum, elle peut grandir jusqu'à
1fr
Le résultat, c'est une grille qui change automatiquement le nombre de colonnes selon la place disponible, tout en gardant des tailles cohérentes.
auto-fill vs auto-fit
La différence entre les deux est subtile :
auto-fillcrée autant de colonnes que possible, même s'il n'y a pas assez d'éléments pour toutes les remplirauto-fitévite de conserver des colonnes vides et laisse les éléments s'étendre
Avec peu d'éléments visibles, auto-fit donne souvent un résultat plus souple.
Cette syntaxe peut sembler un peu dense au début, mais elle devient très pratique dès qu'on commence à faire du responsive.
inline-grid
Comme pour flexbox, il existe aussi une version inline :
display: inline-grid;
Dans ce cas, la grille garde son comportement interne, mais le conteneur lui-même se comporte comme un élément inline.
Ce n'est pas le cas le plus fréquent, mais c'est utile de savoir que cela existe.