Aller au contenu

Le média des artisans du web lundi 19 octobre 2026

Design & UX

CSS Subgrid : aligner des grilles imbriquées sans recalculer leurs dimensions

La valeur subgrid de CSS Grid permet à un composant imbriqué d'hériter des pistes de son parent, ce qui règle enfin l'alignement des cartes et des formulaires à hauteur variable.

Aligner les éléments d’une carte, d’un formulaire ou d’une liste de produits sur une même grille, alors que chaque bloc contient un volume de texte différent, reste un des problèmes récurrents de la mise en page web. Pendant des années, la réponse passait par du JavaScript de mesure, des hauteurs fixes ou des hacks de flexbox. La valeur subgrid de CSS Grid Level 2 règle ce problème nativement : un conteneur imbriqué peut désormais hériter des pistes (lignes ou colonnes) définies par son parent, au lieu de recalculer sa propre grille.

Le problème que subgrid résout

Prenons une rangée de cartes produit : image, titre, description, prix, bouton. Si chaque carte définit sa propre grille interne, rien ne garantit que le titre de la carte 1 et celui de la carte 3 occupent la même hauteur de piste, parce que la description de la carte 3 fait deux lignes de plus. Le résultat visuel : des boutons d’achat qui ne s’alignent plus horizontalement. Historiquement, deux parades existaient : fixer une hauteur arbitraire (qui casse dès que le contenu change) ou mesurer les hauteurs en JavaScript après le rendu (coûteux, et visible sous forme de sursaut de mise en page). subgrid supprime le besoin des deux : la carte ne définit plus ses propres pistes, elle réutilise celles du parent.

Syntaxe : hériter plutôt que redéfinir

La syntaxe reste proche de celle de CSS Grid classique, à un détail près : au lieu de lister des tailles de piste, on écrit subgrid sur grid-template-columns ou grid-template-rows. L’élément doit lui-même être un item de grille positionné sur plusieurs pistes du parent pour que l’héritage ait un sens.

.cartes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto auto 1fr auto;
  gap: 1.5rem;
}

.carte {
  display: grid;
  grid-row: span 5;
  grid-template-rows: subgrid;
}

.carte__titre   { grid-row: 2; }
.carte__description { grid-row: 3; }
.carte__prix    { grid-row: 4; }
.carte__action  { grid-row: 5; }

Chaque .carte s’étend sur les cinq lignes du parent grâce à grid-row: span 5, puis déclare grid-template-rows: subgrid pour réutiliser exactement ces cinq lignes comme sa propre grille interne. Les enfants de chaque carte se positionnent ensuite sur ces lignes avec des numéros qui correspondent à la grille parente, pas à une grille locale recalculée.

Lignes nommées : garder le code lisible dans une grille partagée

Dès qu’une grille dépasse trois ou quatre pistes, les numéros de ligne bruts (grid-row: 2, grid-row: 4) deviennent difficiles à relire, surtout quand plusieurs développeurs interviennent sur les mêmes composants. CSS Grid permet de nommer les pistes, et ces noms se propagent automatiquement aux grilles enfants en subgrid, ce qui évite de les redéclarer à chaque niveau d’imbrication.

.cartes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows:
    [media-debut] auto
    [titre-debut] auto
    [description-debut] auto
    [prix-debut] 1fr
    [action-debut] auto
    [action-fin];
  gap: 1.5rem;
}

.carte {
  display: grid;
  grid-row: media-debut / action-fin;
  grid-template-rows: subgrid;
}

.carte__titre { grid-row: titre-debut; }
.carte__prix  { grid-row: prix-debut; }

Le gain n’est pas seulement esthétique : si une ligne est insérée dans la grille parente, les noms évitent de devoir renuméroter manuellement tous les composants enfants qui référencent les pistes suivantes.

Compatibilité navigateurs

La fonctionnalité est désormais considérée comme Baseline Widely Available, le repère de référence pour juger qu’une fonctionnalité web peut être utilisée sans réserve en production sur l’ensemble du parc de navigateurs modernes.

NavigateurVersion minimale supportant subgrid
Chrome / Edge117
Firefox71
Safari16.0
Opera103
Safari iOS16.0 et suivantes

Pour les projets qui doivent encore couvrir d’anciennes versions de Chrome ou Edge (114 à 116, où la fonctionnalité existait mais était désactivée par défaut), envelopper la déclaration dans une requête de fonctionnalité évite une rupture silencieuse de mise en page : @supports (grid-template-rows: subgrid) { … }, avec un repli en grille classique ou en flexbox dans le bloc par défaut.

Cas d’usage au-delà des cartes produit

Les composants de type « tableau de cartes » (comparatifs tarifaires, fiches équipe, grilles d’articles) bénéficient du même traitement que l’exemple initial : la grille parente fixe le rythme, chaque enfant ne fait qu’occuper les cases qui lui correspondent sans jamais recalculer sa propre géométrie.

Formulaires : un deuxième cas d’usage concret

Les formulaires longs, composés de plusieurs groupes de champs (coordonnées, adresse, paiement), souffrent du même problème que les cartes produit : sans grille partagée, rien ne garantit que les libellés, les champs de saisie et les messages d’erreur s’alignent sur une colonne commune d’un groupe à l’autre. En déclarant une grille de colonnes au niveau du formulaire et en laissant chaque fieldset hériter ces colonnes via grid-template-columns: subgrid, le libellé « Code postal » et le libellé « Numéro de carte » se retrouvent alignés sur la même colonne, même si l’un appartient à un groupe de trois champs et l’autre à un groupe de deux. Le même mécanisme aligne les messages d’erreur sur une colonne dédiée, qu’ils soient présents ou non sur chaque champ, sans réserver un espace vide disgracieux lorsqu’un champ est valide.

Avec subgrid, l’alignement d’une interface cesse de dépendre du contenu le plus long d’une rangée : c’est la grille parente qui impose le rythme, pas le texte le plus verbeux.

Pièges courants

Trois erreurs reviennent le plus souvent en code review. D’abord, oublier que l’élément imbriqué doit occuper plusieurs pistes du parent (grid-row: span n ou grid-column: span n) : sans cela, subgrid n’a rien à hériter et l’élément se comporte comme une grille à une seule piste. Ensuite, mélanger subgrid sur un axe et des dimensions explicites sur l’autre, ce qui est parfaitement valide mais déroute les lecteurs du code si ce n’est pas commenté dans un cas non trivial. Enfin, empiler plusieurs niveaux de subgrid imbriqués les uns dans les autres : le support existe, mais chaque niveau complique le débogage dans les DevTools et alourdit le raisonnement sur l’origine réelle d’une piste.

Le gain va au-delà du confort visuel : il se vérifie à l’usage, notamment pour les équipes qui pratiquaient déjà les container queries pour des composants adaptatifs, puisque les deux fonctionnalités se combinent naturellement, l’une pilotant la taille du conteneur, l’autre l’alignement interne. Associé à des design tokens bien structurés pour les espacements, subgrid permet de construire des grilles de page entièrement pilotées par un nombre réduit de variables, sans dupliquer les valeurs de piste à chaque niveau d’imbrication.

Ce qu’il faut retenir

Subgrid n’ajoute pas de nouvelle capacité spectaculaire à CSS Grid : il retire une limitation. Les grilles imbriquées héritent désormais des pistes de leur parent au lieu de les recalculer, ce qui élimine une classe entière de hacks d’alignement pour les cartes, formulaires et listes à hauteur de contenu variable. Le support navigateur étant désormais large, son adoption ne dépend plus que de la nécessité de maintenir, ou non, un repli pour un public résiduel sur d’anciennes versions.

C’est le genre de fonctionnalité CSS qui ne fait pas de bruit mais qui change vraiment le quotidien : sur mes projets clients, subgrid m’a fait supprimer plusieurs dizaines de lignes de JavaScript de mesure de hauteur que je traînais depuis des années sur des grilles de cartes. Je recommande de l’introduire progressivement, composant par composant, plutôt que de réécrire toute une grille de page d’un coup : les régressions d’alignement sont plus simples à repérer ainsi. — Simon Janvier

Pour aller plus loin : la spécification et les exemples de référence sont détaillés sur MDN, page Subgrid.

Partager LinkedIn Bluesky Hacker News E-mail

À lire aussi