Tutoriel Vidéo CSS display: grid;

Télécharger la vidéo

Je vous propose de découvrir ensemble le nouveau système de grille en CSS (display:grid;). Cette nouvelle disposition va permettre de définir une grille qui sera ensuite utilisée pour placer les éléments enfants.

Quelques liens utiles

Le principe

Prenons le code HTML suivant

<!-- .grid>div*9>lorem -->
<div class="grid">
    <div>lorem</div>
    <div>lorem</div>
    <div>lorem</div>
    <div>lorem</div>
</div>

Pour commencer à utiliser les grilles il faut commencer par définir un display:grid sur notre élément parent et de définir ensuite la taille des colonnes / lignes :

.grid {
    display: grid;
    grid-template-rows: 10% 80% 10%;
    grid-template-columns: 100px 200px;
    /* 
    Ou en racourci 
    grid-template: 10% 80% 10% / 100px 200px;
    */
}

Nous avons ici déclaré 3 colonnes et 2 lignes. Les éléments enfants de notre élément .grid vont alors se placer de manière automatique au sein de la grille que l'on vient de créer. Le quatrième élément se placera automatiquement à la ligne suivante, et de nouvelles lignes seront créées si nécessaire. Il est important de noter que par défaut les éléments vont s'étendre pour occuper l'ensemble de l'espace disponible dans chaque cases (ils prendront ici une hauteur de 100 pixels ou de 200 pixels suivant la ligne qu'ils occupent).

Il est aussi possible de spécifier des "goutières" pour espacer nos différentes lignes / colonnes :

.grid {
    /* ... */
    grid-column-gap: 10px;
    grid-row-gap: 20px;
    /* 
    Ou en racourci 
    grid-gap: 20px 10px;
    */
}

L'utilisation de ces gouttières va entraîner un problème de débordement dans notre cas. L'espace des gouttières va s'ajouter aux tailles spécifiées des colonnes (10% + 20px + 80% + 20px + 10% = 100% + 40px). Pour remédier à ce genre de problématiques, nous avons la possibilité d'utiliser une nouvelle unité de mesure : le fr.
Cette unité de mesure permet de préciser que la colonne/ligne va occuper une portion de l'espace disponible. Si plusieurs colonnes ou plusieurs lignes utilisent cette unité de mesure, l'espace disponible sera fractionné et réparti entre les différents cases.

On peut donc réécrire notre première règle de la manière suivante :

.grid {
    display: grid;
    grid-template-rows: 1fr 8fr 1fr;
    grid-gap: 20px 10px;
}

Cette unité de mesure permet donc de s'assurer que l'ensemble de l'espace disponible sera occupé par nos différentes colonnes.

Comment placer les enfants ?

Une fois cette grille définie, il va être possible de spécifier le placement des éléments enfants au sein de notre grille. Pour cela, on a un ensemble de propriétés qui vont permettre de piloter la colonne de départ et de fin ainsi que la ligne de départ et de fin :

.grid-item {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 2;
  grid-row-end:  span 2; /* L'élément s'étend sur 2 lignes */
  /* racourci
  grid-column: 1 / 3;
  grid-row: 2 / span 1
  */
}

Il est important de noter que les éléments peuvent se chevaucher et vous pouvez ainsi avoir plusieurs éléments qui occupent la même case au sein de votre grille. En revanche, les éléments qui n'ont pas de propriétés grid-column et grid-row vont automatiquement occuper les espaces restants. Il est possible de piloter l'algorithme utilisé pour placer ces éléments grâce à la propriété grid-auto-flow.

  • row, L'algorithme va essayer de remplir chaque ligne avant de passer à la ligne suivante
  • column, L'algorithme va essayer de remplir chaque colonne avant de passer à la colonne suivante
  • dense, L'algorithme va essayer de remplir les cases disponibles automatiquement (attention, cela peut se traduire par un changement d'ordre de vos éléments)

grid-template-areas

Une fonctionnalité intéressante du système de grille est la possibilité de nommer les différentes cases qui la composent. Ceci permettra ensuite de placer les éléments dans ses différentes cases et de pouvoir changer la disposition à volonté depuis l'élément parent. Chose qui peut s'avérer utile pour gérer le responsive par exemple.

Pour nommer nos différentes cases il faudra utiliser la propriété grid-template-area.

.grid {
  grid-template-columns: repeat(4, 50px);
  grid-template-rows: auto;
  grid-template-areas: 
    "header header header header"
    "main main . sidebar"
    "footer footer footer footer";
}

.header {
    grid-area: header;
}

.body {
    grid-area: main;
}

.sidebar {
    grid-area: sidebar;
}

.footer {
    grid-area: footer;
}