Aller au contenu

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 .

HTML
<div class="grid">
    <div class="grid-item">...</div>
    <div class="grid-item">...</div>
    <div class="grid-item">...</div>
</div>
CSS
.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.

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

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

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.

CSS
.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().

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

CSS
.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).
CSS
.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.

CSS
.grid {
    display: grid;
    grid-auto-flow: column dense;
}

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.

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

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

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

CSS
.grid-item {
    grid-column: span 2; /* Etirement sur 2 colonnes */
}

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 :

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

CSS
.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 :

CSS
.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 :

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

CSS
.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 :

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

HTML
<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 :

CSS
#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

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.

CSS
.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: