Apprendre CSS : Grid
Le module « Grid Layout » regroupe un ensemble de propriétés CSS permettant de disposer ses éléments sous forme de lignes et de colonnes.
Le module Grid CSS
« 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 ».
Créer la grille
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>
.grid {
display: grid;
}
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.
<div class="grid">
<div class="grid-item">...</div>
<div class="grid-item">...</div>
<div class="grid-item">...</div>
</div>
.grid {
display: grid;
grid-template-columns: 500px 200px 200px;
}
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.
<div class="grid">
<div class="grid-item">...</div>
<div class="grid-item">...</div>
<div class="grid-item">...</div>
<div class="grid-item">...</div>
</div>
.grid {
display: grid;
grid-template-columns: 200px 500px;
grid-template-rows: 100px 200px;
}
Ici, on définit que :
- La première ligne fait
100px
de haut - La seconde ligne fait
200px
de haut
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.
.grid {
display: grid;
grid-template-columns: 1fr 1fr 2fr;
}
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 */
}
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.
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(200px, 1fr));
}
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.
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
.
.grid {
display: grid;
grid-auto-flow: column dense;
}
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;
}
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 */
}
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 */
}
Etendue
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.
.grid-item {
grid-column: span 2; /* Etirement sur 2 colonnes */
}
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-
.
justify-self
Alignement individuel depuis un élément.
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.
justify-items
Alignement individuel depuis le conteneur.
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;
}
justify-content
Alignement du contenu de la grille.
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.
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-
.
align-self
Alignement individuel depuis un élément.
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.
align-items
Alignement individuel depuis le conteneur.
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;
}
align-content
Alignement du contenu de la grille.
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.
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";
}
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
.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.