Avant CSS Grid, construire une mise en page de page correcte nécessitait des flottants, des clearfix, des marges négatives et une prière pour que vos colonnes ne s'effondrent pas. Flexbox a aidé, mais il est fondamentalement unidimensionnel — vous obtenez une ligne ou une colonne, pas les deux. CSS Grid est le premier système de mise en page natif au CSS réellement conçu pour les mises en page bidimensionnelles. Le défi n'est pas la compatibilité des navigateurs — elle est universelle depuis 2017. Le défi est que l'API a une grande surface et que le nommage est assez incohérent pour être déroutant si vous n'avez pas le modèle sous-jacent bien en tête. Cet article se concentre sur les parties que vous utiliserez dans un vrai travail.
Lignes, colonnes et le conteneur de grille
Tout commence par display: grid sur le conteneur. Une fois défini, les enfants directs deviennent automatiquement des éléments de grille — aucune classe n'est nécessaire sur eux. Vous définissez les pistes de colonnes et de lignes avec grid-template-columns et grid-template-rows.
L'unité clé à comprendre en premier est fr — l'unité fractionnaire. Elle représente une fraction de l'espace disponible dans le conteneur de grille après que les pistes de taille fixe ont été prises en compte. Un 1fr signifie « prendre une part de l'espace restant ». Deux colonnes de 1fr 1fr signifient des moitiés égales. 2fr 1fr signifie que la première colonne obtient deux fois plus que la seconde. C'est l'unité qui rend les grilles fluides naturelles.
/* 3-column blog card layout */
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
gap: 1.5rem;
}
/* repeat(3, 1fr) is shorthand for: 1fr 1fr 1fr */
/* auto rows size to their content */repeat(n, track) est un raccourci pour que vous n'ayez pas à écrire la même taille de piste cinq fois. Il fonctionne également avec des valeurs mixtes : repeat(3, 1fr 2fr) vous donne une grille à 6 colonnes alternant des pistes étroites et larges. Pour les lignes, auto est presque toujours ce que vous souhaitez — les lignes sont dimensionnées selon leur contenu sauf si vous avez besoin d'une hauteur fixe.
<div class="card-grid">
<article class="card">
<img src="/posts/grid-post-1.jpg" alt="CSS Grid post 1">
<h2>Getting Started with Grid</h2>
<p>A practical intro for developers moving from Flexbox.</p>
</article>
<article class="card">
<img src="/posts/grid-post-2.jpg" alt="CSS Grid post 2">
<h2>Grid vs Flexbox</h2>
<p>Which layout tool to reach for, and when.</p>
</article>
<article class="card">
<img src="/posts/grid-post-3.jpg" alt="CSS Grid post 3">
<h2>Responsive Grids Without Media Queries</h2>
<p>Using minmax() to handle reflow automatically.</p>
</article>
</div>La propriété gap
Avant Grid, ajouter de l'espacement entre les enfants de mise en page signifiait des marges — et les marges signifiaient se souvenir de réinitialiser le dernier enfant, gérer l'effondrement et ajouter des marges négatives sur le conteneur pour compenser. gap résout cela proprement. Il ajoute de l'espace uniquement entre les pistes, jamais sur les bords extérieurs de la grille.
/* Uniform gap between all rows and columns */
.card-grid {
gap: 1.5rem;
}
/* Different row and column gaps */
.dashboard {
row-gap: 2rem;
column-gap: 1rem;
}
/* gap is shorthand: row-gap then column-gap */
.dashboard {
gap: 2rem 1rem;
}gap fonctionne également dans Flexbox (il a remplacé l'ancien alias grid-gap). Si vous utilisez déjà Flexbox pour un composant et que vous avez juste besoin d'espacement entre les éléments, vous pouvez utiliser gap là aussi sans passer à Grid.Placement explicite des éléments
Par défaut, les éléments de grille s'écoulent dans la prochaine cellule disponible dans l'ordre source. Mais la véritable puissance de Grid est que vous pouvez placer des éléments n'importe où — et même les faire s'étendre sur plusieurs pistes. Les propriétés sont grid-column et grid-row, qui font référence aux lignes de grille (les lignes entre les pistes, numérotées à partir de 1).
/* Dashboard where the first card spans 2 columns */
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
}
.card--featured {
grid-column: 1 / 3; /* start at line 1, end at line 3 */
}
/* span keyword: simpler when you don't care about exact position */
.card--featured {
grid-column: span 2; /* occupy 2 column tracks from wherever it lands */
}
/* Spanning rows too */
.card--tall {
grid-row: span 2; /* occupy 2 row tracks */
}
/* Explicit positioning: place a panel in column 3-5, row 1-2 */
.sidebar {
grid-column: 3 / 5;
grid-row: 1 / 2;
}Les numéros de lignes commencent à 1 pour le bord gauche/haut et vont jusqu'à n+1 où n est le nombre de pistes. Les numéros de lignes négatifs comptent depuis la droite/bas : grid-column: 1 / -1 étire un élément sur toute la largeur de la grille, quel que soit le nombre de colonnes — un truc utile pour les éléments pleine largeur dans un conteneur à plusieurs colonnes.
grid-template-areas — Nommez votre mise en page
C'est la fonctionnalité qui rend Grid vraiment excellent pour les mises en page au niveau de la page, et c'est l'API la plus lisible de tout CSS. Au lieu de placer des éléments par numéros de lignes, vous dessinez la mise en page comme de l'art ASCII dans le CSS, puis vous indiquez à chaque élément quelle zone nommée il occupe. La spécification grid-template-areas exige que chaque ligne ait le même nombre de cellules, et chaque zone nommée doit être rectangulaire — pas de formes en L.
/* Full page layout: header, sidebar, main, footer */
.page-shell {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 60px 1fr 50px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
gap: 0;
}
.page-header { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-main { grid-area: main; }
.page-footer { grid-area: footer; }<div class="page-shell">
<header class="page-header">Site header / nav</header>
<nav class="page-sidebar">Sidebar navigation</nav>
<main class="page-main">Primary content</main>
<footer class="page-footer">Footer</footer>
</div>Un point (.) dans la chaîne de modèle laisse une cellule intentionnellement vide. Vous pouvez également empiler le même nom sur plusieurs cellules pour les étendre — c'est exactement ce que fait "header header" ci-dessus. Quand vous redimensionnez ou restructurez la mise en page pour différents points de vue, vous mettez à jour la chaîne de modèle en un seul endroit plutôt que de traquer plusieurs déclarations grid-column.
auto-fill vs auto-fit avec minmax()
Le patron derrière les grilles responsives sans requêtes média est l'un des trucs les plus pratiques de Grid : repeat(auto-fill, minmax(250px, 1fr)). Décomposons-le — minmax(250px, 1fr) dit que chaque colonne doit faire au moins 250px de large mais peut s'élargir pour remplir l'espace disponible. auto-fill indique à Grid de créer autant de colonnes que possible dans le conteneur selon cette contrainte. Le résultat est une grille qui gagne et perd automatiquement des colonnes au changement de la fenêtre.
/* Product card grid — reflows automatically, no media queries */
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 1.5rem;
}
/* auto-fit collapses empty tracks — items stretch to fill the container */
.product-grid--stretch {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 1.5rem;
}La différence entre auto-fill et auto-fit est subtile mais importante quand il y a moins d'éléments que de colonnes. Avec auto-fill, Grid réserve de l'espace pour les pistes potentielles même si elles sont vides — les éléments restent à leur largeur minimale. Avec auto-fit, les pistes vides s'effondrent à zéro et les éléments s'élargissent pour remplir la ligne. Pour les grilles de produits et les galeries où vous souhaitez que les éléments utilisent l'espace disponible, auto-fit est généralement plus esthétique. Pour les grilles où une largeur d'élément constante est plus importante que remplir le conteneur, auto-fill est le bon choix.
auto-fill et auto-fit avec minmax() ont une excellente prise en charge — 97%+ mondialement selon caniuse. Vous pouvez utiliser ce patron aujourd'hui sans repli dans tout projet moderne.Alignement dans Grid
Grid utilise le même module d'alignement de boîte que Flexbox, donc les noms de propriétés correspondent directement si vous connaissez déjà Flexbox. Le modèle mental clé : justify opère sur l'axe inline (horizontal dans la plupart des modes d'écriture), align opère sur l'axe de bloc (vertical).
justify-items/align-items— alignement par défaut pour tous les éléments dans leur cellule de grille. La valeur par défaut eststretch, ce qui explique pourquoi les éléments de grille remplissent automatiquement leur cellule.justify-content/align-content— distribue les pistes elles-mêmes dans le conteneur quand la grille est plus petite que le conteneur (similaire àjustify-contentde Flexbox sur le conteneur flex).justify-self/align-self— remplace l'alignement pour un seul élément. Utile quand un élément doit être centré pendant que d'autres s'étirent.- Valeurs :
start,end,center,stretch,space-between,space-around,space-evenly(les trois dernières pour*-contentuniquement).
/* Center all card content within its cell */
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: start; /* cards align to their cell top, not stretched */
gap: 1.5rem;
}
/* Center a single call-to-action card both ways */
.card--cta {
justify-self: center;
align-self: center;
}
/* Distribute tracks with space between — useful for nav bars */
.nav-grid {
display: grid;
grid-template-columns: auto auto auto;
justify-content: space-between;
}Si vous venez de Flexbox, la principale différence est que l'alignement de Grid opère sur un espace bidimensionnel — vous pouvez contrôler les deux axes simultanément. Dans Flexbox, l'alignement sur l'axe transversal s'applique à toute une ligne ou colonne d'éléments ; dans Grid, chaque élément a sa propre cellule, donc justify-self et align-self vous donnent un contrôle par élément sans nécessiter d'éléments enveloppants.
Mise en page réelle : coquille de tableau de bord complète
Voici une structure de page CSS Grid complète pour une application de tableau de bord — en-tête, barre latérale de navigation réductible, zone de contenu principal avec sa propre grille interne et pied de page. C'est le patron que vous utiliseriez comme coquille de mise en page la plus externe pour un tableau de bord SaaS ou un panneau d'administration.
/* ── Dashboard shell ──────────────────────────────────── */
.dashboard-shell {
display: grid;
grid-template-columns: 220px 1fr;
grid-template-rows: 56px 1fr 44px;
grid-template-areas:
"topbar topbar"
"sidenav content"
"sidenav footer";
min-height: 100vh;
}
.dashboard-topbar { grid-area: topbar; background: #1e293b; }
.dashboard-sidenav { grid-area: sidenav; background: #0f172a; overflow-y: auto; }
.dashboard-content { grid-area: content; padding: 1.5rem; overflow-y: auto; }
.dashboard-footer { grid-area: footer; background: #f8fafc; border-top: 1px solid #e2e8f0; }
/* ── Collapsed sidebar variant ────────────────────────── */
.dashboard-shell--collapsed {
grid-template-columns: 56px 1fr;
}
/* ── Content area — internal card grid ─────────────────── */
.dashboard-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
grid-template-rows: auto;
align-content: start;
gap: 1.25rem;
}
/* Stat cards take one column each; the main chart spans all */
.stat-card { /* auto-placed, one column */ }
.main-chart { grid-column: 1 / -1; } /* always full width */
/* ── Responsive: collapse to single-column on small screens */
@media (max-width: 768px) {
.dashboard-shell {
grid-template-columns: 1fr;
grid-template-rows: 56px 1fr auto 44px;
grid-template-areas:
"topbar"
"content"
"sidenav"
"footer";
}
}<div class="dashboard-shell">
<header class="dashboard-topbar">
<a href="/dashboard" class="brand">AppName</a>
<nav class="topbar-actions">
<button class="btn-icon" aria-label="Notifications">
<span class="icon-bell"></span>
</button>
<img src="/avatar/user.png" class="user-avatar" alt="User menu">
</nav>
</header>
<nav class="dashboard-sidenav">
<ul>
<li><a href="/dashboard">Overview</a></li>
<li><a href="/dashboard/analytics">Analytics</a></li>
<li><a href="/dashboard/users">Users</a></li>
<li><a href="/dashboard/settings">Settings</a></li>
</ul>
</nav>
<main class="dashboard-content">
<div class="stat-card">Monthly Revenue</div>
<div class="stat-card">Active Users</div>
<div class="stat-card">Churn Rate</div>
<div class="main-chart">Revenue Chart (full width)</div>
</main>
<footer class="dashboard-footer">
<p>AppName v2.4.1 — <a href="/status">System Status</a></p>
</footer>
</div>Quelques points à noter dans cet exemple. Le pied de page est placé dans la colonne sidenav sur les grands écrans en utilisant la définition de zone de modèle, ce qui le maintient visuellement séparé de la zone de défilement du contenu principal. Le 1fr sur les lignes et overflow-y: auto sur le volet de contenu signifie que la zone de contenu défile indépendamment — la barre supérieure et le sidenav restent fixes, ce qui est l'UX standard du tableau de bord. La requête @media en bas réorganise les zones de grille pour mobile sans toucher du tout au HTML.
Conclusion
La courbe d'apprentissage de CSS Grid vient principalement du nommage — lignes, pistes, zones, unités fr — mais une fois que le modèle clique, c'est remarquablement direct. Pour les mises en page réelles : utilisez grid-template-areas pour les coquilles de page (ça ressemble à un wireframe), utilisez repeat(auto-fit, minmax()) pour les grilles de cartes responsives, et utilisez grid-column: span N explicite pour les éléments qui brisent le flux standard. Vous n'avez pas besoin de toute l'API de Grid pour 90% du vrai travail — ces patrons en couvrent la majeure partie.
Pour aller plus loin : le Guide complet CSS-Tricks de Grid est la meilleure référence en une seule page ; la documentation CSS Grid de MDN va en profondeur sur chaque propriété ; et la spécification CSS Grid Level 1 du W3C est étonnamment lisible si vous voulez comprendre le comportement exact des cas limites. La compatibilité des navigateurs est excellente — consultez caniuse.com/css-grid pour les chiffres actuels. Si vous travaillez sur un projet en direct et souhaitez nettoyer votre CSS, le formateur CSS sur ce site nettoiera et embellira vos feuilles de style.