Le grid : guide du débutant

Publié le

Auteur

Adem Duran

Qu’est-ce que le grid ?

Le grid est un système de mise en page. Il est basé sur une grille en deux dimensions que l’on peut définir selon notre besoin. Le grid est supporté par la totalité des navigateurs récents. Il existe des fonctionnalités expérimentales que nous ne développerons pas dans cet article. Pour vérifier si les technologies front-end que vous utilisez sont compatibles, vous pouvez vous rendre sur CanIUse, qui vous permettra de visualiser la compatibilité d’une feature sur différents navigateurs.

Lexique

Avant d’entrer dans le vif du sujet, il y a un certain nombre de termes à expliciter ! Le grid possède son propre champ lexical. Il est nécessaire de l’expliciter afin de comprendre les attributs que l’on va utiliser tout au long de cet article.

Line :

Les lignes viennent définir la grille. Elles peuvent être verticales (on parlera dans ce cas de colonnes) et horizontales (on parlera dans ce cas de lignes). Elles sont également numérotées, en allant de gauche à droite et de haut en bas. La numérotation de la grille commence à 1. Prenons l’exemple d’une grille 3 x 3 :

Cell :

Une cellule constitue l’unité d’espace le plus petit de la grille. Elle se situe entre deux lignes consécutives.

Container :

C’est l’élément sur lequel le découpage de la grille sera défini, il contient les éléments à placer dans la grille. On parle également d’élément parent.

Item :

Ce sont les éléments qui seront placés au sein de la grille. On parle également d’élément enfant.

Vous remarquez qu’un item est identique à une cell. En pratique, la taille par défaut d’un item est celle d’une cell mais elle peut être modifiée. Sur notre grille 3×3, un élément enfant peut très bien occuper un espace de 2 colonnes et 2 lignes, comme sur le schéma suivant :

Dans cette configuration, votre grille peut donc en théorie ne contenir au maximum que 6 items.

Area :

Le grid area est une zone qui est constituée de plusieurs cellules.

Gap :

Le grid gap est l’espace entre les cellules. Il est comparable à la gouttière en typographie.

Exemples :

Nous allons définir une structure et un style communs à tous les exemples. Pour le HTML, voici le code :

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <title>Exemple</title>
</head>
<body>

    <main>
        <div>
            
        </div>
    </main>
    
</body>

La première balise link permet d’ajouter la police « Poppins » au projet, elle est facultative.

Exemple simple

Pour cet exemple, nous allons créer une grille 3×3 comme dans le lexique.

Dans un premier temps on va créer une structure basique.

<div class="wrapper">
      <div class="element">
            <p>Element 1</p>
      </div>
      <div class="element">
            <p>Element 2</p>
      </div>
      <div class="element">
            <p>Element 3</p>
      </div>
      <div class="element">
            <p>Element 4</p>
      </div>
      <div class="element">
            <p>Element 5</p>
      </div>
      <div class="element">
            <p>Element 6</p>
      </div>
      <div class="element">
            <p>Element 7</p>
      </div>
      <div class="element">
            <p>Element 8</p>
      </div>
      <div class="element">
            <p>Element 9</p>
      </div>
</div>

Ensuite, on va appliquer du style pour définir les dimensions de la grille.

.simple {
    display: grid;
    grid-template-columns: 250px 250px 250px;
    grid-template-rows: 250px 250px 250px;
    grid-gap: 10px;
    justify-content: center;
}

Ici, l’attribut CSS display: grid; indique au navigateur que l’élément ayant la classe « wrapper » va contenir une grille. Les deux prochaines lignes : grid-template-columns: 250px 250px 250px; et grid-template-rows: 250px 250px 250px;; définissent les dimensions de la grille. La grille contient donc 3 colonnes de 250px et 3 lignes de 250px.

Afin de rendre la grille plus lisible, on va ajouter du gap de 10px entre chaque élément de la grille grâce à cette ligne : grid-gap: 10px;. L’alignement de la grille est indiqué grâce à cet attribut : justify-content: center;

Enfin, on va styliser les éléments enfants (items) pour visualiser notre grille. Libre à vous de changer le style en fonction de vos besoins ou de vos envies.

.element {
    background-color: #d3d3d3;
    display: flex;
}
.element > p {
    margin: auto;
}

Note : on utilise ici une bonne pratique du web afin de centrer un élément enfant par rapport à son parent. Il faut ajouter l’attribut display: flex; au parent et margin: auto; à l’enfant et la magie opère !

Voici le résultat :

Exemple avancé

Allons un peu plus loin ! Pour cet exemple, nous allons utiliser l’attribut grid-template-areas. Il nous permettra de disposer les éléments de la grille selon notre convenance.

Pour commencer, on va définir notre grille avec une nouvelle méthode.

.advanced {
    display: grid;
    grid-template-columns: repeat(5, 250px);
    grid-auto-rows: 250px;
    grid-gap: 10px;
    justify-content: center;
}

On retrouve une nouvelle manière de définir les dimensions de notre grille ! grid-template-columns: repeat(5, 250px); nous permet de définir 5 colonnes de 250px, nous évitant ainsi d’écrire grid-template-columns: 250px 250px 250px 250px 250px;. Lors de la définition de grandes grilles, la fonction repeat() devient primordiale si l’on veut optimiser son code.

L’attribut grid-auto-rows: 250px; indique que l’on veut créer automatiquement des lignes de 250px. La grille contiendra donc autant de lignes que nécessaire à la dimension indiquée.

grid-template-areas nous permet de placer les items de notre grille selon notre convenance. Avant cela, il faut que nous nommions chaque élément de notre grille.

Plutôt que d’ajouter une classe pour chaque item, nous allons utiliser un sélecteur CSS qui va grandement nous faciliter la tâche !

.advanced > :nth-child(1) {
    grid-area: element1;
}
.advanced > :nth-child(2) {
    grid-area: element2;
}
.advanced > :nth-child(3) {
    grid-area: element3;
}
.advanced > :nth-child(4) {
    grid-area: element4;
}
.advanced > :nth-child(5) {
    grid-area: element5;
}
.advanced > :nth-child(6) {
    grid-area: element6;
}
.advanced > :nth-child(7) {
    grid-area: element7;
}
.advanced > :nth-child(8) {
    grid-area: element8;
}
.advanced > :nth-child(9) {
    grid-area: element9;
}

Le sélecteur :nth-child(n)sélectionne le n-ième enfant de l’élément parent sélectionné, en partant de 1. On peut remplacer n par even ou odd qui choisira respectivement les enfants pairs et impairs. Il est même possible d’utiliser des suites pour indiquer les enfants que l’on souhaite sélectionner (exemple : 4n+1 ou 7n+5).

Il ne nous reste plus qu’à placer les éléments comme on le souhaite dans notre grille :

.advanced {
    display: grid;
    grid-template-columns: repeat(5, 250px);
    grid-auto-rows: 250px;
    grid-gap: 10px;
    justify-content: center;
    grid-template-areas: "element1 element1 element2 element3 element4"
                         "element1 element1 element5 element3 element6"
                         "element7 element7 element8 element8 element9";
}

Attention : il existe quelques règles à respecter lors de la répartition des items dans l’area. Votre élément doit rester rectangulaire, cette répartition ne fonctionnera pas :

grid-template-areas: "element1 element1 element2 element3 element4"
                     "element1 element1 element1 element5 element6"
                     "element7 element7 element8 element8 element9";

De la même manière, vous ne pouvez pas définir un même élément à deux endroits séparés comme dans l’exemple suivant :

grid-template-areas: "element1 element1 element2 element3 element4"
                     "element9 element9 element5 element3 element6"
                     "element7 element7 element8 element8 element9";

Voici le résultat :

Exemple complexe

Ce dernier exemple va plus loin et va proposer une grille plus sophistiquée. Prenons le cas d’une page qui est séparée en deux sections. Dans la page partie gauche, il y aura les dernières actualités du moment et dans la partie droite, une « sidebar » qui contient une section « À propos » et « Catégories » à la manière d’un site WordPress.

Dans un premier temps, on va construire la structure HTML de toute la page. On y inclura également un header et footer.

Concernant le header, le titre sera compris dans une balise span et le menu sera une liste.

On obtient donc cette structure :

<header>
        <span>Exemple de grid</span>
        <ul>
            <li>Simple</li>
            <li>Avancé</li>
            <li>Complexe</li>
        </ul>
</header>

Le contenu principal contiendra les dernières actualités et la sidebar. Une disposition en grille sera utilisée pour présenter les derniers articles de la page. On devra donc inclure, comme dans les exemples précédents, des divisions avec la classe « element ». Pour la sidebar, on utilisera la balise aside, prévue à cet effet.

La balise main est structurée de cette manière :

<main>
      <div class="complex">
          <div>
              <h2>Dernières actualités</h2>
              <div class="grid">
                  <div class="element t2x2">
                      <p>1</p>
                  </div>
                  <div class="element">
                      <p>2</p>
                  </div>
                  <div class="element t1x2">
                      <p>3</p>
                  </div>
                  <div class="element t2x1">
                      <p>4</p>
                  </div>
                  <div class="element">
                      <p>5</p>
                  </div>
                  <div class="element t1x2">
                      <p>6</p>
                  </div>
                  <div class="element">
                      <p>7</p>
                  </div>
                  <div class="element t2x1">
                      <p>8</p>
                  </div>
                  <div class="element">
                      <p>9</p>
                  </div>
                  <div class="element t2x1">
                      <p>10</p>
                  </div>
                  <div class="element">
                      <p>11</p>
                  </div>
                  <div class="element">
                      <p>12</p>
                  </div>
              </div>               
          </div>
          <aside>
              <div class="about">
                  <h3>À propos</h3>
                  <hr>
                  <p>Nullam eget nibh nec ante gravida varius quis vel erat. Nulla ac dapibus arcu, id tempus lacus. Nullam eros lectus, rutrum quis libero quis, tincidunt convallis purus. Etiam in tincidunt ligula.</p>
              </div>
              <div class="categories">
                  <h3>Catégories</h3>
                  <hr>
                  <ul>
                      <li><a href="#">Catégorie 1</a></li>
                      <li><a href="#">Catégorie 2</a></li>
                      <li><a href="#">Catégorie 3</a></li>
                      <li><a href="#">Catégorie 4</a></li>
                      <li><a href="#">Catégorie 5</a></li>
                  </ul>
              </div>          
          </aside>
      </div>
</main>

Enfin, le footer contiendra une balise span avec les copyrights (ici, seulement pour avoir une structure de page complète).

<footer>
        <span>© 2021 Première Place. Tous droits réservés.</span>
</footer>

Pour les couleurs de cette page on utilisera des variables CSS, afin de nous simplifier la stylisation. Les styles pour le body, le header et le footer ne sont que des exemples et peuvent être modifiés selon vos envies.

:root {
    --black: #2b2d42;
    --gray: #8d99ae;
    --white: #edf2f4;
    --red: #d90429;  
}

body {
    padding: 0;
    margin: 0;
    background-color: #eee;
    font-family: 'Poppins', sans-serif;
}

/*// Header //*/

header {
    background-color: var(--red);
    display: flex;
    align-items: center;
    color: var(--white);
    padding: 20px 100px;
}
header > span {
    margin-right: auto;
    font-weight: bold;
}
header > ul {
    list-style-type: none;
    display: flex;
}
header > ul > li {
    margin: 0px 20px;
    font-weight: 600;
}

Passons au style de la grille. On va définir deux grilles. La première aura pour but de séparer les dernières actualités et la sidebar tandis que la deuxième va servir à présenter les derniers articles. Le CSS pour la balise de classe « complex » sera :

.complex {
    display: grid;
    grid-template-columns: 5fr 2fr;
}

Pour les éléments enfants de cette balise, une couleur de fond et du padding seront définis :

.complex > div, aside {
    background-color: var(--white);
    padding: 50px;
}

La grille qui présente les articles sera définie de sorte qu’elle ajustera son agencement selon la largeur de l’écran (il faudra tout de même penser aux breakpoints) grâce à la fonction repeat();. Concrètement, la grille répètera autant de colonnes que possible sur l’espace disponible. Allons encore plus loin en lui définissant une taille de colonne entre 100 et 300px grâce à la fonction minmax();. La hauteur des lignes sera de 300px. La grille contiendra autant de lignes que nécessaire, c’est-à-dire que selon le contenu le nombre de lignes variera. On ajoutera une gouttière pour rendre la grille plus lisible. On ajoute un attribut CSS (grid-auto-flow) qui nous permettra de choisir de quelle manière seront placés les éléments dans la grille, étant donné que cela se fait de manière automatique. Enfin on va également centrer notre grille.

On obtient donc :

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(100px, 300px));
    grid-auto-rows: 300px;
    grid-gap: 15px;
    grid-auto-flow: dense;
    justify-content: center;
}

auto-fill permet d’ajuster l’agencement de la grille.dense, quant à lui, indique à l’algorithme de placement des éléments que la grille doit être dense, c’est-à-dire que l’on comble des trous quitte à ne plus respecter l’ordre des éléments.

Vous avez pu remarquer que certains items avaient une classe supplémentaire (t2x2, t1x2 ou t2x1). Ces classes vont nous permettre de définir des éléments qui vont s’étendre sur plusieurs cellules. Pour cela, chaque classe contiendra les attributs raccourcis grid-columnet grid-row. Ils permettent de définir les emplacements de début et de fin et la taille de l’élément sur lequel la classe est ajoutée.

Voici les styles de classes :

.t2x2 {
    grid-row: span 2;
    grid-column: span 2;
}
.t1x2 {
    grid-row: span 2;
    grid-column: span 1;
}
.t2x1 {
    grid-row: span 1;
    grid-column: span 2;
}

span 1 indique que l’élément prendra la taille d’une cellule. D’une manière générale, span xindique que l’élément prendra une taille de X cellule(s).

Il ne nous reste plus qu’à ajouter du style pour la sidebar et le footer. En voici un exemple :

aside > div {
    margin-bottom: 50px;
}

footer {
    background-color: var(--red);
    color: var(--white);
    padding: 50px 100px;
}

Voici le résultat :

Et voilà, vous avez maintenant les bases pour appliquer des grid layout sur vos prochains sites !