frontend / css
Grid avancé
Explication
Ce que vous allez apprendre
- Distinguer
justify-items/align-items(contenu de la cellule) dejustify-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-flowetgrid-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 sur | Effet visible seulement si... |
|---|---|---|
justify-items / align-items | Le contenu à l'intérieur de chaque cellule | Toujours applicable |
justify-content / align-content | La grille entière dans son conteneur | La 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.
/* 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;
}/* 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) */
}/* 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;
}/* 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 *//* 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-itemspositionnent le contenu dans chaque cellule ;-contentpositionne la grille elle-même.- Superposer des éléments dans Grid ne nécessite ni
position: absoluteni z-index compliqué. grid-auto-flow: densecomble les trous, au prix de réordonner visuellement certains items.subgridrésout l'alignement de grilles imbriquées, un problème historiquement pénible en CSS.
Exercices pratiques
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.