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.

Icône de calendrier
Débutant
9 chapitres

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 ».

copié !
<div class="grid">
	<div class="grid-item">...</div>
	<div class="grid-item">...</div>
	<div class="grid-item">...</div>
</div>
copié !
.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.

copié !
<div class="grid">
	<div class="grid-item">...</div>
	<div class="grid-item">...</div>
	<div class="grid-item">...</div>
</div>
copié !
.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.

copié !
<div class="grid">
	<div class="grid-item">...</div>
	<div class="grid-item">...</div>
	<div class="grid-item">...</div>
	<div class="grid-item">...</div>
</div>
copié !
.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.

copié !
.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().

copié !
.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.

copié !
.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 comme auto-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 entre min-content et max-content de sorte que la taille des cellules soit adaptative. Il correspond au calcul minmax(min-content, max-content).
copié !
.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.

copié !
.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.

copié !
.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épart
  • grid-column-end : définit le numéro de colonne avant laquelle s’arrêter (et implicitement son étendue)
copié !
.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épart
  • grid-row-end : définit le numéro de ligne avant laquelle s’arrêter (et implicitement son étendue)
copié !
.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.

copié !
.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.

copié !
.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.

copié !
.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 :

copié !
.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.

copié !
.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 :

copié !
.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 :

copié !
.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.

copié !
.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 :

copié !
.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 et grid-template-rows : dans ce cas-là, les lignes et cellules de la grille pourront avoir des tailles différentes.
copié !
.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 :

copié !
<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 :

copié !
#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 ou grid-template-areas
  • Modifiant l’étendue d’un élément avec grid-column ou grid-area
copié !
.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.