10. Grid Layout¶
"Grid Layout" est un module CSS dont le rôle est de faciliter le placement des éléments sur une page web. On parle de "module" car il s’agit d’un ensemble de propriétés CSS fonctionnant les unes avec les autres.
Le concept général de Grid Layout (ou positionnement en grille ) consiste à diviser virtuellement une page web en lignes et en colonnes (invisibles), à la manière d’un tableau. Grid permet donc une mise en page à deux dimensions.
Les zones formées par les intersections entre ces lignes et colonnes sont appelées cellules .
Grid vs Flexbox
À la différence de Flex, Grid est une méthode de placement à deux dimensions.
Déclarer un conteneur¶
Pour déclarer que l’on va disposer des éléments dans une grille, on applique la propriété display: grid
sur une balise.
Cet élément deviendra ainsi le grid-container et ses enfants directs des grid-items .
<div class="grid">
<div class="grid-item">...</div>
<div class="grid-item">...</div>
<div class="grid-item">...</div>
</div>
Par défaut, display: grid
va définir une grille constituée d’une seule colonne et empiler les éléments contenus les uns sous les autres.
Un conteneur de grille se comporte comme un block , il est néanmoins possible de le transformer en élément inline avec display: inline-grid
.
Définir des colonnes¶
Avec la propriété grid-template-columns
, on découpe la largeur de la page en colonnes.
Ici, on définit que :
- La première colonne fait
500px
de large - La seconde et la troisième colonne font
200px
de large
Si le nombre de grid-items dépasse le nombre de colonnes définies, alors une seconde ligne sera créée en dessous.
Définir des lignes¶
Avec la propriété grid-template-rows
, on définit plusieurs lignes.
Ici, on définit que :
- La première ligne fait
100px
de haut - La seconde ligne fait
200px
de haut
Attention
N’abusez pas de cette propriété. On préférera dans la plupart des cas laisser le contenu d’un bloc en définir sa hauteur. C’est en revanche parfois utile pour avoir la main pleine sur l’apparence de la grille (damier de jeu, galerie photos…)
S’il est possible de dimensionner nos cellules en pixels, nous ferons la plupart du temps usage des unités, mots-clés et fonctions ci-dessous afin de créer de véritables grilles responsives.
L'unité fr
¶
Si la largeur d’une colonne ou la hauteur d’une ligne est définie en px
, alors elle sera fixe. Néanmoins, il est tout à fait possible de travailler avec des unités flexibles.
Pour cela, on privilégiera l’unité fr
, représentant une fraction de l’espace disponible (selon width
et height
) dans le conteneur de la grille.
Pour calculer l’espace occupé par une fraction, il suffit de diviser le nombre de fr
défini pour une colonne / ligne par le nombre de fr
total de colonnes / lignes.
Ici, on définit que :
- La première colonne / ligne occupe une fraction du conteneur (ici 25%).
1 / 4 = 0.25
- La seconde colonne / ligne occupe une fraction du conteneur (ici 25%).
1 / 4 = 0.25
- La troisième colonne occupe 2 fractions du conteneur (ici 50%).
2 / 4 = 0.5
La fonction repeat()
¶
Une fonctionnalité particulièrement intéressante du positionnement en grille est de pouvoir appliquer des motifs de répétition de colonnes ou de lignes (appelés patterns ) avec la fonction repeat()
.
.grid {
display: grid;
grid-template-columns: 500px repeat(2, 1fr); /* Equivalent 500px 1fr 1fr */
}
Vous remarquez d’ailleurs qu’il est tout à fait possible de mélanger des tailles flexibles et absolues.
La fonction minmax()
¶
Souvent utilisée en argument de la fonction repeat()
, la fonction minmax()
définit un intervalle de valeurs possibles pour la taille des cellules.
Ici, les 3 cellules feront au minimum 200px
et occuperont chacune au maximum 1/3
du conteneur.
Les mots-clés auto-fill
et auto-fit
¶
Les grids CSS vont nous offrir une mécanique permettant de gérer le responsive sans passer par la moindre media-query. Cela est rendu possible avec les mots-clés auto-fill
et auto-fit
qui vont permettre de définir automatiquement le nombre de colonnes à créer.
auto-fill
: cette propriété va remplir la ligne avec autant de colonnes que possible. Si les colonnes créées par nos éléments HTML ne suffisent pas à remplir la ligne, alors des colonnes vides seront ajoutées occupant malgré tout un espace.auto-fit
: cette propriété fonctionne commeauto-fill
, à la différence qu’elle remplira l’espace disponible dans le conteneur en agrandissant la taille des cellules
Les mots-clés auto
, min-content
et max-content
¶
Outre les unités absolues comme le px
ou flexibles comme le fr
, certains mots-clés permettent d’adapter la taille des cellules à leur contenu.
min-content
: correspond à la taille minimale nécessaire pour le contenu. Pour un contenu textuel, cela provoquera un retour à la ligne après chaque mot ; la largeur de la colonne correspondra ainsi au mot le plus long.max-content
: correspond à la taille maximale nécessaire pour le contenu. Pour un contenu textuel, cela ne provoquera pas de retour à la ligne ; la largeur de la colonne correspondra ainsi au texte entier.auto
: correspond dans la plupart des cas à l’intervalle entremin-content
etmax-content
de sorte que la taille des cellules soit adaptative. Il correspond au calculminmax(min-content, max-content)
.
.grid {
display: grid;
/* Fonctionne également avec grid-template-rows */
grid-template-columns: min-content max-content auto;
}
Placement automatique¶
Par défaut, les éléments d’une grille sont organisés en remplissant chacune des lignes au fur et à mesure, quitte à en ajouter si besoin. C’est en réalité la propriété grid-auto-flow
qui définit cela avec pour valeur par défaut row
.
En modifiant cette valeur à column
, alors les éléments seront organisés en remplissant chacune des colonnes au fur et à mesure, quitte à en ajouter si besoin.
Définir la propriété grid-auto-flow: column
implique bien entendu d’avoir défini plusieurs lignes avec grid-template-rows
.
Sur une grille, il est possible que des trous apparaissent. Ces trous sont représentés par des cellules vides qui peuvent être créées par :
- Le positionnement d’un élément sur certaines lignes et colonnes. Alors il se peut que la place qu’ils laissent entre eux ne permette pas de placer tous les éléments dans l’ordre.
- L’étirement d’un élément sur plusieurs cellules. Alors il se peut que la place restante sur la ligne ne permette pas de positionner l’élément suivant à la suite.
Pour éviter cela, il est possible de dire à l’algorithme de placement de remplir les trous éventuels. Cela se fait en ajoutant le mot-clé dense
à la suite de row
ou column
.
Information
Les notions de positionnement et d’étirement sont évoquées plus bas dans ce cours.
Espacements¶
Les propriétés column-gap
et row-gap
permettent respectivement de définir des espacements entre les colonnes et les lignes de nos éléments.
gap
est une propriété abrégée permettant de les combiner.
.grid {
display: grid;
grid-template-columns: 200px 500px;
grid-template-rows: 100px 200px;
/* Equivalent à column-gap: 20px et row-gap: 20px */
gap: 20px;
}
Information
Pour espacer les éléments d’une grille, utiliser gap
est préférable que d’utiliser margin
ou padding
car ces deux dernières propriétés vont également placer des espacements à l’extérieur des éléments, provoquant souvent des défauts d’alignement.
Positionnement¶
Lorsqu’on déclare un positionnement en grille, tous les enfants du grid-container seront automatiquement affectés à la première cellule disponible dans la grille.
Si pour une quelconque raison vous souhaitez modifier ce comportement par défaut et étirer des éléments sur plusieurs colonnes / lignes, alors vous devrez connaître quelques propriétés de positionnement utiles.
Le positionnement consiste à définir pour un élément son emplacement de départ ainsi que son étendue (= sa taille).
Positionnement sur des colonnes¶
Pour positionner un élément sur des colonnes précises, on utilise les propriétés grid-column-start
et grid-column-end
.
grid-column-start
: définit le numéro de colonne de départgrid-column-end
: définit le numéro de colonne avant laquelle s’arrêter (et implicitement son étendue)
.grid-item {
grid-column-start: 2; /* Commence à la seconde colonne */
grid-column-end: 4; /* Termine à la troisième colonne */
}
Positionnement sur des lignes¶
Pour positionner un élément sur des lignes précises, on utilise les propriétés grid-row-start
et grid-row-end
.
grid-row-start
: définit le numéro de ligne de départgrid-row-end
: définit le numéro de ligne avant laquelle s’arrêter (et implicitement son étendue)
.grid-item {
grid-row-start: 2; /* Commence à la seconde ligne */
grid-row-end: 4; /* Termine à la troisième ligne */
}
Information
Si grid-column-start
et grid-row-start
indiquent commence sur cette colonne / ligne , grid-column-end
et grid-row-end
indiquent termine avant cette colonne / ligne .
Syntaxes alternatives¶
Les propriété grid-column
et grid-row
sont respectivement des raccourcis des propriétés grid-column-start
/ grid-column-end
et grid-row-start
/ grid-row-end
.
Elles offrent alors 3 syntaxes alternatives.
Point de départ /
point d'arrivée
La syntaxe avec un /
entre la valeur de départ et d’arrivée.
.grid-item {
grid-column: 2 / 4; /* Commence à la seconde colonne et termine à la troisième colonne */
}
Point de départ /
span
étendue
La syntaxe avec /
entre la valeur de départ et l’étendue souhaitée.
Cette étendue est définie par le mot-clé span
suivi du nombre de colonnes / lignes sur lesquelles s’étendre.
.grid-item {
grid-column: 2 / span 2; /* Commence à la seconde colonne et termine à la troisième colonne */
}
Étendue
Utilisé seul, le mot-clé span
signifie que les éléments doivent s’étendre sur un certain nombre de colonnes, sans leur spécifier de point de départ ou d’arrivée. Ils seront alors placés les uns à la suite des autres, sans trou.
Information
Ce fonctionnement est bien entendu le même pour grid-row
.
Alignement¶
Au sein d’une grille, il va être possible de modifier l’alignement des éléments selon un axe spécifique.
L’alignement d’un élément est défini selon 2 axes :
- L’axe des lignes inline
- L’axe des blocs block
Alignement en ligne¶
L’axe des lignes correspond à l’axe sur lequel on écrit ; il s’agit de l’axe horizontal (X).
Pour aligner des éléments selon l’axe en ligne, on utilisera les propriétés commençant par justify-
.
Alignement individuel depuis un élément: justify-self
¶
La propriété justify-self
permet d’aligner un élément dans sa cellule selon l’axe en ligne. Cette propriété prend généralement les valeurs suivantes :
.grid-item {
justify-self: stretch; /* Défaut */
justify-self: start;
justify-self: center;
justify-self: end;
}
stretch
(défaut) : l’élément est étiré au maximum au sein de la cellule, selon l’axe en ligne.center
: l’élément est aligné au centre de la cellule, selon l’axe en ligne.start
: l’élément est aligné au début de la cellule, selon l’axe en ligne.end
: l’élément est aligné à la fin de la cellule, selon l’axe en ligne.
Alignement individuel depuis le conteneur: justify-items
¶
Pour aligner l’ensemble des éléments dans leurs cellules respectives selon l’axe en ligne, on utilisera plutôt justify-items
sur le conteneur de la grille. Cette propriété possède les mêmes valeurs que justify-self
.
.grid {
justify-items: stretch; /* Défaut */
justify-items: start;
justify-items: center;
justify-items: end;
}
Concrètement, appliquer justify-items
sur le conteneur revient à appliquer justify-self
sur chacun des éléments contenus dans la grille.
Alignement du contenu de la grille: justify-content
¶
La propriété justify-content
permet d’aligner toutes les cellules dans la grille selon l’axe en ligne. Cette propriété prend généralement les valeurs suivantes :
.grid {
justify-content: start; /* Défaut */
justify-content: center;
justify-content: end;
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;
}
start
(défaut) : les éléments sont alignés au début de la grille, selon l’axe en ligne.center
: les éléments sont alignés au centre de la grille, selon l’axe en ligne.end
: les éléments sont alignés à la fin de la grille, selon l’axe en ligne.space-between
: les éléments sont espacés équitablement au sein de la grille, selon l’axe en ligne.space-around
: les éléments sont espacés équitablement au sein de la grille, selon l’axe en ligne. Un espace mesurant la moitié de l’espace séparant deux éléments est créé avant le premier élément et après le dernier élément.space-evenly
: les éléments sont espacés équitablement au sein de la grille, selon l’axe en ligne. Un espace identique est aussi créé avant le premier élément et après le dernier élément.
Cette propriété ne sera en toute logique effective que si la somme des width
des cellules est inférieure à la width
de la grille.
Alignement en bloc¶
Pour aligner des éléments selon l’axe de bloc, on utilisera les propriétés commençant par align-
.
L’axe des blocs est perpendiculaire à l’axe des lignes, il correspond à l’axe sur lequel les blocs apparaissent ; il s’agit de l’axe vertical (Y).
Pour aligner des éléments selon l’axe de bloc, on utilisera les propriétés commençant par align-
.
Alignement individuel depuis un élément: align-self
¶
La propriété align-self
permet d’aligner un élément dans sa cellule selon l’axe de bloc. Cette propriété prend généralement les valeurs suivantes :
.grid-item {
align-self: stretch; /* Défaut */
align-self: start;
align-self: center;
align-self: end;
}
stretch
(défaut) : l’élément est étiré au maximum au sein de la cellule, selon l’axe de bloc.center
: l’élément est aligné au centre de la cellule, selon l’axe de bloc.start
: l’élément est aligné au début de la cellule, selon l’axe de bloc.end
: l’élément est aligné à la fin de la cellule, selon l’axe de bloc.
Information
La valeur baseline
peut aussi être utilisée mais son usage est bien plus spécifique.
Alignement individuel depuis le conteneur: align-items
¶
Pour aligner l’ensemble des éléments dans leurs cellules respectives selon l’axe de bloc, on utilisera plutôt align-items
sur le conteneur de la grille.
Concrètement, appliquer justify-items
sur le conteneur revient à appliquer justify-self
sur chacun des éléments. Cette propriété possède les mêmes valeurs que align-self
.
.grid {
align-items: stretch; /* Défaut */
align-items: start;
align-items: center;
align-items: end;
}
Information
La valeur baseline
peut aussi être utilisée mais son usage est bien plus spécifique.
Alignement du contenu de la grille: align-content
¶
La propriété align-content
permet d’aligner toutes les cellules dans la grille selon l’axe de bloc. Cette propriété prend généralement les valeurs suivantes :
.grid {
align-content: start; /* Défaut */
align-content: center;
align-content: end;
align-content: space-between;
align-content: space-around;
align-content: space-evenly;
}
start
(défaut) : les éléments sont alignés au début de la grille, selon l’axe de bloc.center
: les éléments sont alignés au centre de la grille, selon l’axe de bloc.end
: les éléments sont alignés à la fin de la grille, selon l’axe de bloc.space-between
: les éléments sont espacés équitablement au sein de la grille, selon l’axe de bloc.space-around
: les éléments sont espacés équitablement au sein de la grille, selon l’axe de bloc. Un espace mesurant la moitié de l’espace séparant deux éléments est créé avant le premier élément et après le dernier élément.space-evenly
: les éléments sont espacés équitablement au sein de la grille, selon l’axe de bloc. Un espace identique est aussi créé avant le premier élément et après le dernier élément.
Attention
Cette propriété ne sera en toute logique effective que si la somme des height
des cellules est inférieure à la height
de la grille.
Information
La combinaison justify-*
et align-*
peut être abrégée par la propriété raccourcie place-*
.
Zones de grille nommées¶
L’approche par template consiste à nommer les cellules d’une grille. Pour cela, on ajoutera une propriété grid-template-areas
au niveau de conteneur de la grille.
Nommer les cellules¶
La propriété grid-template-areas
peut être utilisée :
- Seule : dans ce cas-là elle définit par la même occasion que chaque ligne et colonne de la grille occuperont un espace de
1fr
. - Avec les propriétés
grid-template-columns
etgrid-template-rows
: dans ce cas-là, les lignes et cellules de la grille pourront avoir des tailles différentes.
.grid {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: 80px 1fr 60px;
grid-template-areas:
"head head"
"sidebar main"
"sidebar foot";
}
Information
Si je n’avais pas défini les propriétés grid-template-columns
et grid-template-rows
, alors grid-template-areas
aurait implicitement indiqué les valeurs grid-template-columns: 1fr 1fr
et grid-template-rows: 1fr 1fr 1fr
Positionner les éléments¶
Considérons la structure HTML suivante :
<div id="page">
<header>HEADER</header>
<aside type="info">SIDEBAR</aside>
<main>MAIN</main>
<footer>FOOTER</footer>
</div>
Une fois nos cellules nommées, nous allons désormais être en mesure de les positionner de manière plus visuelle qu’avec les propriétés grid-column
et grid-row
. Cela se fera avec grid-area
:
#page {
display: grid;
gap: 1rem;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"head head"
"sidebar main"
"sidebar foot";
}
#page > header {
grid-area: head;
}
#page > aside {
grid-area: sidebar;
}
#page > main {
grid-area: main;
}
#page > footer{
grid-area: foot;
}
Grille responsive¶
Côté media-queries, rendre une grille responsive est un jeu d’enfant en :
- Modifiant le nombre de colonnes d’un conteneur avec
grid-template-columns
ougrid-template-areas
- Modifiant l’étendue d’un élément avec
grid-column
ougrid-area
Media-queries ?
Vous vous dites: mais c'est quoi les media-queries, ne vous en faites pas! Je vous explique tous en détail dans le prochain cours.
.gallery {
display: grid;
gap: 1rem;
}
.gallery > img {
width: 100%;
}
@media screen and (min-width: 768px) {
.gallery {
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (min-width: 1280px) {
.gallery {
grid-template-columns: repeat(3, 1fr);
}
}
Sans passer par des media-queries, la combinaison repeat(auto-fit, minmax(200px, 1fr))
s’avère redoutable pour ajuster automatiquement le nombre de colonnes à la largeur de l’écran.
Guide interactif
Rien de mieux qu'un guide interactif pour mieux comprendre le fonctionnement de Grid Layout. Guide Interactif
mettez la page en français!
Grid responsive
Retrouvez ici un exemple complet de classes pour former une grid CSS responsive pour différentes interfaces en utilisant la technique de media-query : responsive-grid.css
Apprendre le positionnement en s’amusant
Voici deux sites vous permettant d’expérimenter l'usage de Grid de manière interactive et ludique: