Blog

Display: grid;

#CSS

Illustration de Display: grid;

Présentation

CanIUse

display: grid est une nouvelle propriété CSS qui permet de réaliser rapidement des structures de page et d'éléments de page grâce à un système de grille.

Cette propriété transforme une zone en quadrillage où on pourra définir des colonnes et lignes.

CanIUse

Selon CanIUse.com, elle est aujourd'hui comprise par tous les navigateurs. Cependant, il reste un mauvais élève Internet Explorer.

L'avantage est de pouvoir gérer le placement des éléments directement depuis le parent (contrairement aux flexbox). Ainsi avec la propriété display: grid;, on pourra définir la largeur d'une colonne depuis le parent : ce qui est très pratique pour le responsive.

Cas concret

Installation

Installation d'un site statique avec :

{
  "name": "super-site",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "browser-sync start --server --watch --files \"html/*.html\" \"css/*.css\"",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "browser-sync": "^2.24.4"
  }
}

Notre objectif sera de créer le layout d'un blog. Voici la struture de notre HTML :

<html>
  <head>
    <title>Mon super site</title>
    <link rel="stylesheet" href="/style.css">
  </head>
  <body>
    <section id="layout">
      <header>
          <nav>
            <a href="">Mon super site</a>
            <a href="">Actualité</a>
            <a href="">Notre équipe</a>
          </nav>
          <section></section>
      </header>
      <aside id="pub"><h2>Votez Baka !</h2></aside>
      <section id="body">
        <article>
          <img src="/images/baka.jpg" alt="">
          <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Minima ea totam omnis, dolorum dolorem debitis accusantium velit! Obcaecati esse libero rerum? Cum et numquam laboriosam animi corporis, doloremque nulla perspiciatis.</p>
          <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Minima ea totam omnis, dolorum dolorem debitis accusantium velit! Obcaecati esse libero rerum? Cum et numquam laboriosam animi corporis, doloremque nulla perspiciatis.</p>
          <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Minima ea totam omnis, dolorum dolorem debitis accusantium velit! Obcaecati esse libero rerum? Cum et numquam laboriosam animi corporis, doloremque nulla perspiciatis.</p>
          <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Minima ea totam omnis, dolorum dolorem debitis accusantium velit! Obcaecati esse libero rerum? Cum et numquam laboriosam animi corporis, doloremque nulla perspiciatis.</p>
        </article>
      </section>
      <footer>
          <section id="newsletter">
              <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Minima ea totam omnis, dolorum dolorem debitis accusantium velit! Obcaecati esse libero rerum? Cum et numquam laboriosam animi corporis, doloremque nulla perspiciatis.</p>
          </section>
        </footer>
    </section>
  </body>
</html>

Definition de colonnes et de lignes : la constitution d'une grille

Définir des zones : grid-template-columns et grid-template-rows

Pour commencer, il faut définir le template comme une grille, soit :

#layout {
  display: grid;
}

🎉 Tada !!!! Voilà, merci de m'avoir lu : à bientôt !

Bon d'accord, rien ne s'est passé. Toute la force des grilles reposent sur la définition de colonnes et des lignes. Pour cela, c'est la propriété grid-template-column qui nous intéresse.

Cette propriété grid-template-column accepte des valeurs de mesure. Ces valeurs de mesure correspondent au largeur de colonne : une valeur égale une colonne. Les valeurs acceptées sont celles de mesure standard comme la mesure en pourcentage ou en pixel.

Une nouvelle mesure est également disponible la fraction. La fraction (fr) correspond à la fraction de votre écran.

Faisons un petit test :

#layout {
  display: grid;
  grid-template-columns: 200px 1fr;
}

Le navigateur va créer une grille avec deux colonnes : la première de 200px et l'autre d'une fraction prenant ainsi tout l'espace restant.

Pour bien comprendre, écrivons :

#layout {
  display: grid;
  grid-template-columns: 200px 2fr 1fr;
}

Nous obtenons alors : une colonne de 200px et avec le restant de l'espace disponible, une colonne prenant 2/3 de l'espace disponible ainsi qu'une autre prenant 1/3 de l'espace disponible.

Notez que grâce au fabuleux navigateur Firefox, vous pouvez cliquer sur l'icône de grille et voir s'afficher les zones de celle-ci par-dessus vos éléments sur votre page. Pour les chromaddictes, l'affichage de la grille est au survol du DOM.

Pour les lignes, ce sera le même fonctionnement avec la propriété grid-template-rows.

Nommer des zones de grilles : grid-template-areas

Il existe également une méthode plus nominative pour définir des colonnes et des lignes, c'est la propriété grid-template-areas.

Cette méthode consiste a nommer chaque zone de la grille pour l'attribuer par la suite à ces enfants. C'est d'ailleurs ce que nous allons utiliser pour notre exemple.

Nous voulons :

  • une ligne avec le header,
  • une ligne avec l'encart de pub occupant 1/3 de la zone et avec le contenu de la page,
  • une ligne avec le footer

Résultat :

#layout {
  display: grid;
  grid-template-areas:
    "header header header"
    "pub body body"
    "footer footer footer";
}

On attribuera ensuite les noms aux propriétés grid-area aux enfants :

header {
  background-color: #C0C0ff;
  grid-area: header;
}

footer {
  background-color: #FFC089;
  grid-area: footer;
}

#pub {
  background-color: #C0d700;
  grid-area: pub;
}

#body {
  background-color: #0F89FF;
  grid-area: body;
}

Avec cette méthode, on réalise rapidement un layout global d'un site.

Occupation d'une zone spécifiée sur l'enfant

Dans la majorité des cas, il nous faut une grille plutôt régulière pour agencer un site. Après un savant calcul mental, je vais faire une grille de 12 colonnes.

Alors, vous allez me dire que c'est bien laborieux d'écrire 12 fois 1fr : vous avez raison. Voici une fonction raccourci :

.grid {
  display: grid;
  grid-template: auto / repeat(12, 1fr);
}

Utilisons cette nouvelle grille sur la balise header. Dedans nous voulons que :

  • une section soit collé à droite et soit large de 3fr,
  • la zone de navigation prenne l'espace restant et que les éléments enfants (les liens) prennent le plus d'espace autour d'eux.

Pour la section :

header > section {
  background: red;
  height: 20px;
  grid-column-start: 8;
  grid-column-end: 12;
  /* raccourcis :*/
  grid-column: 8 / 12;
}

Pour la barre de navigation :

nav {
  background: grey;
  grid-column: 1 / 8;
}

A noter qu'on peut aussi utiliser une valeur d'espacement, appelée span, pour définir la zone de l'élément. Par exemple, on peut aussi écrire :

header > section {
  background: red;
  height: 20px;
  grid-column: 8 / span 4;
}

Faire des classes génériques de placement (col s1/s2/s3/...)

Quand on fait une grille, on peut avoir envie de créer des class génériques avec des largeurs définis.

Dans ce cas, on pourrait écrire :

.col4 {
  grid-column-end: span 4;
}

.col8 {
  grid-column-end: span 8;
}

Placement des éléments à l'intérieur

display: grid retrouve globalement les mêmes propriétés que les flexbox pour placer les éléments.

Par exemple, si on veut placer de la pub pour Baka mon petit chat centrée horizontalement et verticalement, on ajoute :

#pub {
  ...
  display: grid;
  grid-template: auto / 1fr; /* ligne automatique et une colonne */
  justify-content : center; /* alignement horizontal */
  align-items: center; /* alignement vertical */
}

IE 10/11

Internet Explorer est hélas encore une fois, notre mauvais élève du jour. En effet, IE connait certaines propriétés.

Un très bon article sur le sujet avec des conseils pour palier ce manque : https://rachelandrew.co.uk/archives/2016/11/26/should-i-try-to-use-the-ie-implementation-of-css-grid-layout/

Pour des cas plus complexe, on peut se rediriger vers cette librairie de polyfill : https://github.com/FremyCompany/css-grid-polyfill

Quelques sources