- CSS Subgrid est une fonctionnalité qui dépasse les limites de Grid en permettant d’étendre la structure de la grille parente jusqu’aux éléments DOM enfants
- Jusqu’ici, seuls les enfants directs pouvaient participer à la grille, mais avec subgrid, des structures imbriquées comme
<ul> et <li> peuvent elles aussi partager la même répartition en cellules de grille
- Cela permet de corriger les déséquilibres entre éléments frères causés par des longueurs de contenu différentes, et de construire des mises en page où chaque carte ou section réagit dynamiquement
- Il faut toutefois garder en tête certains points d’attention, comme la réservation des lignes, la réinitialisation des numéros de ligne et l’incompatibilité avec les grilles fluides basées sur
auto-fill
- La fonctionnalité est prise en charge par les principaux navigateurs, et son adoption progressive peut fortement améliorer à terme la souplesse de conception des UI
Concept de base de Subgrid
- À l’origine, CSS Grid ne permettait qu’aux éléments enfants directs de participer à la mise en page
- Par exemple, dans une UI de portfolio, les images des
<li> à l’intérieur d’un <ul> se retrouvaient par défaut regroupées dans une seule cellule
- En utilisant
grid-template-rows: subgrid et grid-template-columns: subgrid, on hérite de la définition des lignes et colonnes de la grille parente
- Chaque
<li> peut alors être placé directement dans une cellule de la grille parente, ce qui permet de conserver à la fois une structure HTML sémantique et un alignement visuel cohérent
- Le même résultat peut être obtenu avec Flexbox et des Grid imbriquées, mais subgrid propose une approche plus simple grâce au partage d’une structure de grille unique
De nouvelles possibilités de mise en page
- Dans l’exemple de cartes de portfolio, chaque
<article> utilise une grille à 2 colonnes pour disposer image et texte
- L’unité
fr est flexible, mais comme chaque carte calcule sa grille indépendamment, cela crée des déséquilibres de largeur de colonnes
- En appliquant
grid-template-columns: subgrid, toutes les cartes partagent les proportions de colonnes de la grille parente
- L’ensemble de la grille se réajuste automatiquement en fonction des variations de contenu, comme la longueur des titres
- Cette approche permet de créer une mise en page à conscience mutuelle entre éléments frères
- Exemple : si l’on raccourcit le titre « Infinite Supercomputer », les proportions image/texte de toutes les cartes s’ajustent immédiatement
Points d’attention lors de l’utilisation de Subgrid
Réservation de l’espace des lignes
- Le partage des colonnes est intuitif, mais le partage des lignes exige une réservation explicite
- Exemple : dans des cartes de grille tarifaire, pour que les éléments de chaque
<ul> s’alignent sur les mêmes lignes, il faut définir le nombre de lignes avec grid-row: span N
- Par défaut, subgrid n’occupe qu’une seule cellule ; pour utiliser plusieurs lignes, il faut d’abord étendre la zone de grille parente
Numérotation dans les grilles imbriquées
- Subgrid hérite du modèle de lignes et colonnes du parent, mais les numéros de ligne sont réinitialisés
- Par exemple, même si les lignes 2 à 5 du parent sont héritées, elles seront renumérotées de 1 à 4 à l’intérieur
- Chaque grille possède son propre index ; les numéros de ligne fonctionnent donc comme des indices relatifs, et non comme des identifiants uniques
Incompatibilité avec les grilles fluides
- Une grille fluide de type
repeat(auto-fill, minmax()) ne peut pas être utilisée avec subgrid
- Subgrid nécessite un nombre de colonnes défini, et ne prend pas en charge
auto-fill ni auto-fit
- L’auteur précise ne pas avoir trouvé de solution à cette combinaison
Prise en charge des anciens navigateurs
- La fonctionnalité est prise en charge par les principaux navigateurs depuis 2023, mais le taux de compatibilité reste inférieur à 90 %
- On peut fournir une mise en page de repli via la condition
@supports not (grid-template-columns: subgrid)
- Exemple : proposer un fallback où l’image et le texte sont disposés en empilement vertical
Cas concret et conclusion
- Le site développeur de Stripe (
stripe.dev) construit toute la page comme une grande grille, avec plusieurs niveaux de subgrid pour obtenir un placement précis
- Subgrid est utile non seulement pour les grandes mises en page, mais aussi pour de petits ajustements d’UI
- Il peut être introduit progressivement, sans avoir à refondre l’ensemble d’un projet
- C’est un nouveau moyen de gagner en souplesse dans les mises en page CSS, avec un fort potentiel pour des usages expérimentaux
1 commentaires
Avis sur Hacker News
La fonctionnalité subgrid est vraiment géniale, mais dans le premier exemple simple, on pourrait aussi utiliser
ul { display: contents }pour faire participer les enfants à la mise en page en grilleSi la fonctionnalité subgrid n’est pas indispensable, cette approche est plus efficace
display: contentsretire complètement l’élément UL de la mise en pageOn ne peut donc pas lui appliquer de style ni recevoir des événements UI sur cet élément
Si on veut utiliser l’UL comme zone de surbrillance ou section défilable, subgrid est bien plus utile
fr, et de réserverfrau texte pour qu’il occupe l’espace restantJ’en ai vraiment bavé autrefois faute de subgrid en construisant une UI de comparaison de prix
Il était impossible d’aligner les lignes de deux tableaux placés côte à côte
On pouvait s’en sortir avec une hauteur fixe ou des calculs en JS, mais dans une structure de composants React, c’était beaucoup trop inefficace
Je me suis demandé si les container queries n’étaient pas une meilleure solution
Mais pour préserver la cohérence de l’ensemble de la grille, subgrid peut être plus adapté
À titre de référence, le CodePen d’exemple aide à bien comprendre
En plus, utiliser un container crée un nouveau stacking context, ce qui est contraignant
C’est dommage de ne pas pouvoir utiliser subgrid et container ensemble. Si les enfants pouvaient référencer la taille du subgrid, ce serait vraiment puissant
Ça donne l’impression qu’on est « finalement revenus à une mise en page en <table> ? »
<table>étaient un hack pour résoudre un problème, avec beaucoup de limites en accessibilité et de contraintes techniquesLe système Grid est un outil de disposition visuelle, différent d’un tableau qui représente une structure de données
Maintenant que la grille s’est imposée comme standard, j’aimerais qu’on arrête de la comparer aux tableaux
Mais ni le responsive ni l’accessibilité n’étaient pris en compte. Au fond, on a simplement réinventé les tableaux
<table>, c’est que c’était une structure destinée à décrire le contenu. La grille en elle-même n’a rien de problématiqueAu final, CSS a simplement réimplémenté cette fonctionnalité sous une forme améliorée
L’un des bugs de grid que j’ai rencontrés autrefois était qu’en donnant à un élément
<img>une taille en pourcentage, la taille de la cellule se retrouvait déformée par la taille native de l’imageÇa se produisait à la fois dans Firefox et Chromium, et le bug correspondant figure dans Mozilla Bug 1857365
width/heightfixesC’est dommage que CSS oblige parfois à ajouter des informations de structure du document juste pour la mise en page
Par exemple, devoir indiquer explicitement le nombre de lignes
Ou bien ce serait bien si un conteneur flex pouvait imiter la distribution d’un autre conteneur
Mais cela risquerait de rendre la DX plus complexe
Je me demandais pourquoi les exemples de code mettaient des styles à la fois dans les fichiers HTML et CSS
En regardant uniquement le CSS du premier exemple subgrid, j’ai longtemps cherché quel style était appliqué à l’UL
Ça donne l’impression qu’on est « finalement revenus à grid ? »
On faisait déjà quelque chose de similaire à l’époque du HTML ancien style
Les billets de blog de Josh sont toujours impressionnants
La clarté de l’écriture, le sens du design, jusqu’au site web interactif, tout est excellent
Personnellement, je trouve toujours grid difficile à manipuler
La syntaxe me paraît maladroite et j’ai du mal avec sa logique de mise en page. Flexbox est bien plus intuitif et flexible
Flexbox contrôle la taille à partir du contenu, tandis que Grid le fait à partir du conteneur
Le contenu ne s’ajuste pas automatiquement sur plusieurs axes, et il faut tout positionner manuellement
Soit je comprends mal la nature même de grid, soit cela correspond mal au type de travail que je fais