Il y a quelques années, je me suis assis pour construire un tableau de bord. Rien de bien sorcier — juste une barre latérale fixe, une zone de contenu principale et un pied de page. Flexbox semblait être le choix évident et, au début, tout fonctionnait. Puis, j'ai ajouté une rangée de cartes dans la section principale. Toute la mise en page s'est effondrée. J'ai passé les trois heures suivantes à lutter avec les ratios flex-grow et des largeurs en pourcentage imbriquées, regardant des conteneurs refuser de s'aligner, peu importe la quantité de padding que je retirais. La page ressemblait à une tour sur le point de s'écrouler.

Cette expérience éprouvante m'a appris la chose la plus importante concernant la mise en page CSS moderne : Flexbox et Grid ne sont pas des rivaux. Ce sont des outils destinés à des tâches différentes, et la plupart des échecs de mise en page proviennent de l'utilisation du mauvais outil.

La différence est dimensionnelle

Considérez Flexbox comme un couloir. Les éléments circulent dans une seule direction, soit en ligne, soit en colonne. Il est conçu pour une distribution unidimensionnelle. Le navigateur examine le contenu, puis décide comment l'étirer, le réduire ou l'aligner le long de cet axe unique. Cela rend Flexbox parfait pour les situations où le contenu dicte la mise en page. Une barre de navigation, une pile de champs de formulaire ou un ensemble de tags nécessitant un espacement égal se placent tous naturellement dans un conteneur flex car ils partagent une seule logique de ligne.

Grid, en revanche, est un plan d'étage. Il est strictement bidimensionnel, gérant les lignes et les colonnes simultanément. Vous définissez d'abord la structure, puis vous placez les éléments à l'intérieur. Cela rend Grid idéal pour l'architecture globale d'une page — partout où vous avez besoin de contrôler conjointement le positionnement vertical et horizontal. Lorsque vous essayez de forcer une conception bidimensionnelle complexe via des conteneurs Flexbox imbriqués, vous vous retrouvez avec un marquage profond, des conteneurs fragiles et des calculs précaires qui s'effondrent dès que vous ajoutez un élément supplémentaire.

Flexbox mérite toujours sa place

Ne vous précipitez pas pour remplacer chaque conteneur flex par Grid. À l'intérieur de composants individuels, Flexbox est souvent plus propre et plus intuitif. Si vous avez un pied de page de carte avec deux boutons et que vous voulez en aligner un à gauche et l'autre à droite, justify-content: space-between fait exactement ce que vous voulez. Si vous devez centrer verticalement une icône à l'intérieur d'un bouton de hauteur inconnue, align-items: center est la méthode la plus simple. Le contenu variable — comme une rangée de badges d'utilisateurs avec des longueurs de noms différentes — s'intègre confortablement dans Flexbox car il privilégie le contenu. Le conteneur s'adapte à ce qu'il contient.

Grid privilégie le conteneur. Vous dites au navigateur combien de pistes existent et quelle doit être leur taille, puis vous déposez les éléments dans ces cellules. Si votre mise en page n'est en réalité qu'une seule ligne d'éléments frères partageant l'espace, Grid ajoute un formalisme inutile.

La mise en page appartient à Grid

C'est ici que Grid prend le relais. Vous souvenez-vous de mon cauchemar de tableau de bord ? Voici à quoi la structure aurait dû ressembler dès le départ :

.page {
  display: grid;
  min-height: 100vh;
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 200px 1fr;
}

.header { grid-row: 1; grid-column: 1 / -1; }
.sidebar { grid-row: 2; grid-column: 1; }
.main { grid-row: 2; grid-column: 2; }
.footer { grid-row: 3; grid-column: 1 / -1; }

Regardez ce qui se passe. Le conteneur .page établit trois lignes et deux colonnes. La première ligne s'ajuste à ce que contient l'en-tête grâce à auto. La ligne du milieu occupe tout l'espace restant disponible avec 1fr. Le pied de page se place dans la dernière ligne, dimensionné selon son propre contenu. Pendant ce temps, la barre latérale est fixée à 200 pixels de large, et la zone principale remplit le reste.

La logique de placement est un véritable soulagement. L'en-tête s'étend de la ligne de colonne 1 à la ligne -1, ce qui signifie qu'il s'étire sur les deux colonnes, peu importe le nombre de colonnes que vous ajouterez plus tard. La barre latérale et le contenu principal partagent la ligne 2 mais occupent des colonnes distinctes. Le pied de page reprend toute la largeur dans la ligne 3. Vous n'avez pas besoin de calculs en pourcentage sur les éléments enfants. Vous n'avez pas besoin de conteneurs imbriqués qui se battent pour la hauteur. Modifiez la largeur de la barre latérale à un seul endroit, et la zone principale s'ajuste automatiquement. L'ensemble de la mise en page respire comme un système unique.

Lisibilité avec grid-template-areas

Pour encore plus de clarté, vous pouvez nommer vos sections. Au lieu de gérer des numéros de lignes, vous écrivez une carte visuelle :

.page {
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
}

.header { grid-area: header; }
.main { grid-area: main; }

Désormais, votre feuille de style se lit comme un wireframe. Si vous souhaitez que la barre latérale apparaisse à droite pour un autre point de rupture, il vous suffit d'échanger deux mots dans la chaîne de template. Ce genre de lisibilité structurelle est impossible à atteindre dans une tour de conteneurs flex imbriqués.

Deux leçons difficiles

Grid n'est pas magique. Il existe deux erreurs qui détruiront rapidement votre mise en page.

Le premier point est l'utilisation imprécise des unités. Si vous définissez grid-template-columns: 1fr 1fr 1fr mais que votre design n'a besoin que de deux colonnes de contenu, cette troisième piste existe toujours. Elle restera soit vide, créant un espace inattendu, soit elle forcera votre contenu réel à se compresser d'une manière qui brisera votre design. Soyez intentionnel. Quand vous voulez deux colonnes, écrivez repeat(2, 1fr).