Retour au cours

frontend / css

Grid avancé

Leçon 81 exercice

Explication

Ce que vous allez apprendre

  • Distinguer justify-items/align-items (contenu de la cellule) de justify-content/align-content (grille entière)
  • Superposer plusieurs éléments dans une même cellule de grille sans position: absolute
  • Contrôler la génération automatique de lignes avec grid-auto-flow et grid-auto-rows
  • Construire un agencement irrégulier façon magazine avec span
  • Aligner des grilles imbriquées entre elles grâce à subgrid

Dans quel contexte ?

Sur une page de galerie photo galerie.html, un développeur veut superposer un dégradé sombre et une légende par-dessus chaque image, sans recourir à du position: absolute fragile qui casse dès que la taille de l'image change. En plaçant l'image et l'overlay dans la même cellule de grille (grid-column: 1; grid-row: 1; sur les deux), la grille gère elle-même l'alignement de la superposition, sans calcul de coordonnées manuel.

Étape 1 : au-delà de la grille simple

Une fois les bases de Grid maîtrisées (colonnes, lignes, zones nommées), des besoins plus fins apparaissent dans un vrai projet : centrer un contenu dans sa cellule, superposer plusieurs éléments, ou construire un agencement irrégulier façon magazine.

Étape 2 : deux échelles d'alignement à ne pas confondre

Voici un piège fréquent pour qui vient de Flexbox : justify-items/align-items positionnent le CONTENU à l'intérieur de chaque cellule, tandis que justify-content/align-content positionnent la GRILLE ENTIÈRE dans son conteneur.

Étape 3 : pourquoi ce piège rend perplexe

Confondre les deux mène à des résultats qui semblent ne "rien faire", alors que la propriété agit simplement à la mauvaise échelle — justify-content n'a par exemple aucun effet visible si la grille remplit déjà tout son conteneur.

PropriétéAgit surEffet visible seulement si...
justify-items / align-itemsLe contenu à l'intérieur de chaque celluleToujours applicable
justify-content / align-contentLa grille entière dans son conteneurLa grille est plus petite que son conteneur

Piège fréquent

justify-content: center sur une grille qui remplit déjà 100% de son conteneur n'a visuellement aucun effet — il n'y a tout simplement pas d'espace supplémentaire à répartir. Si un centrage semble "ne rien faire" en Grid, vérifiez d'abord si c'est justify-items (le contenu) qu'il fallait utiliser.

Étape 4 : superposer sans position: absolute

Une fois l'alignement clair, voici une découverte qui simplifie beaucoup de cas : on peut placer plusieurs éléments dans EXACTEMENT la même cellule de grille, créant une superposition propre — par exemple un dégradé de texte par-dessus une image.

Étape 5 : pourquoi c'est plus simple que le positionnement classique

Contrairement au positionnement absolu, aucun calcul de coordonnées manuel n'est nécessaire ici : la grille se charge elle-même d'aligner les deux éléments superposés.

Étape 6 : subgrid, un vieux problème enfin résolu

Il reste un cas historiquement difficile : aligner le contenu de plusieurs cartes indépendantes, par exemple faire coïncider tous leurs titres sur la même ligne. subgrid permet à une grille imbriquée d'hériter directement les pistes de son parent, garantissant un alignement parfait entre plusieurs blocs.

Bonne pratique

Pour aligner parfaitement les titres, prix et boutons d'une rangée de cartes produit dont le contenu varie en longueur, utilisez subgrid plutôt que de fixer des hauteurs arbitraires : chaque carte hérite alors les pistes exactes de la grille parente.

Et ensuite ?

Une fois Grid maîtrisé en profondeur, la prochaine étape consiste à sortir des éléments du flux normal avec le positionnement et à comprendre le stacking context.

Commandes & code

Grid avancé

Alignement précis, grilles implicites, superposition de contenus, et magazine layout.

css
/* Alignement du contenu DANS chaque cellule (comme align-items/justify-content en flex) */
.grille {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    justify-items: center;  /* horizontal, par cellule */
    align-items: center;    /* vertical, par cellule */
}

/* Alignement de LA GRILLE ENTIÈRE dans son conteneur (si plus petite que lui) */
.grille {
    justify-content: center; /* centre les colonnes s'il reste de l'espace horizontal */
    align-content: center;
}

/* Override par item */
.item-special {
    justify-self: end;
    align-self: start;
}
css
/* Grille implicite : que se passe-t-il pour les items en trop ? */
.grille {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 120px;          /* taille des lignes générées automatiquement */
    grid-auto-flow: row;            /* défaut : remplit ligne par ligne */
    grid-auto-flow: column;         /* remplit colonne par colonne à la place */
    grid-auto-flow: dense;          /* comble les trous laissés par des items larges (réordonne visuellement) */
}
css
/* Superposition de contenus : plusieurs éléments dans la même cellule */
.carte-image {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
}
.carte-image img,
.carte-image .overlay {
    grid-column: 1;
    grid-row: 1; /* les deux occupent EXACTEMENT la même cellule -> superposition */
}
.carte-image .overlay {
    align-self: end;
    background: linear-gradient(transparent, rgba(0,0,0,0.7));
    color: white;
    padding: 16px;
}
css
/* Magazine layout : combinaison span + placement explicite */
.galerie {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: 150px;
    gap: 12px;
}
.galerie .grande   { grid-column: span 2; grid-row: span 2; }
.galerie .large    { grid-column: span 2; }
.galerie .haute    { grid-row: span 2; }
/* combiné à grid-auto-flow: dense, les petits items comblent
   automatiquement les trous laissés par les grands */
css
/* subgrid : hérite les pistes du parent -- aligne des grilles imbriquées entre elles */
.carte-liste {
    display: grid;
    grid-template-columns: subgrid;
    grid-column: span 3; /* la carte occupe 3 colonnes du parent... */
    /* ...et ses PROPRES enfants s'alignent sur CES MÊMES colonnes,
       même si plusieurs cartes ont des contenus de tailles différentes */
}

Résumé

  • justify-items/align-items positionnent le contenu dans chaque cellule ; -content positionne la grille elle-même.
  • Superposer des éléments dans Grid ne nécessite ni position: absolute ni z-index compliqué.
  • grid-auto-flow: dense comble les trous, au prix de réordonner visuellement certains items.
  • subgrid résout l'alignement de grilles imbriquées, un problème historiquement pénible en CSS.

Exercices pratiques

1 disponible
1

Mission : une galerie photo dont le centrage ne fait rien

Objectif : Distinguer l'alignement de cellule de l'alignement de grille entière, et construire une superposition sans position absolute.

Contexte

Sur galerie.css, .galerie est en display: grid; grid-template-columns: repeat(4, 1fr); width: 100%; et remplit déjà toute la largeur de son conteneur. Un développeur ajoute justify-content: center; en espérant centrer les vignettes qui semblent légèrement décalées, mais rien ne change visuellement. Par ailleurs, chaque vignette doit afficher une légende semi-transparente collée en bas de l'image, sans JavaScript ni position absolute.

Résoudre l’exercice →