CSS Flexbox vs Grid : Quand utiliser lequel

· 12 min de lecture

Table des matières

Choisir entre CSS Flexbox et Grid peut sembler accablant, surtout lorsque les deux semblent capables de résoudre les mêmes problèmes de mise en page. La vérité est qu'ils sont conçus pour des objectifs différents, et comprendre leurs forces fera de vous un développeur plus efficace.

Ce guide détaille tout ce que vous devez savoir sur Flexbox et Grid, des concepts de base aux applications réelles. À la fin, vous saurez exactement quel outil utiliser dans n'importe quel scénario de mise en page.

Les bases de Flexbox (mise en page 1D)

Flexbox est conçu pour les mises en page unidimensionnelles — organiser les éléments dans une seule ligne ou colonne. Il excelle dans la distribution de l'espace et l'alignement des éléments le long d'un axe, ce qui le rend parfait pour les barres de navigation, les groupes de boutons et le contenu qui s'écoule dans une seule direction.

Concepts de base

Chaque mise en page Flexbox a un conteneur flex (parent) et des éléments flex (enfants). Le conteneur contrôle la direction, l'enroulement et l'alignement de ses éléments :

/* Le conteneur flex */
.container {
  display: flex;
  flex-direction: row;      /* row | row-reverse | column | column-reverse */
  justify-content: center;  /* Alignement de l'axe principal */
  align-items: center;      /* Alignement de l'axe transversal */
  gap: 1rem;                /* Espace entre les éléments */
  flex-wrap: wrap;          /* Permettre aux éléments de passer à la ligne suivante */
}

/* Éléments flex */
.item {
  flex: 1;                  /* Grandir pour remplir l'espace disponible */
  /* Raccourci pour : flex-grow: 1; flex-shrink: 1; flex-basis: 0; */
}

.item-fixed {
  flex: 0 0 200px;          /* Ne pas grandir, ne pas rétrécir, 200px de large */
}

Comprendre les axes principal et transversal

La clé pour maîtriser Flexbox est de comprendre ses deux axes. L'axe principal s'étend dans la direction définie par flex-direction (horizontal pour row, vertical pour column). L'axe transversal s'étend perpendiculairement à celui-ci.

Ce système d'axes détermine quelles propriétés contrôlent quelles dimensions. justify-content fonctionne toujours sur l'axe principal, tandis que align-items fonctionne sur l'axe transversal.

Propriétés d'alignement

/* Axe principal (horizontal dans la direction row) */
.container {
  justify-content: flex-start;   /* Par défaut : regrouper les éléments au début */
  justify-content: flex-end;     /* Regrouper les éléments à la fin */
  justify-content: center;       /* Centrer les éléments */
  justify-content: space-between;/* Espace égal entre les éléments */
  justify-content: space-around; /* Espace égal autour des éléments */
  justify-content: space-evenly; /* Espace égal partout */
}

/* Axe transversal (vertical dans la direction row) */
.container {
  align-items: stretch;    /* Par défaut : étirer pour remplir le conteneur */
  align-items: flex-start; /* Aligner en haut */
  align-items: flex-end;   /* Aligner en bas */
  align-items: center;     /* Centrer verticalement */
  align-items: baseline;   /* Aligner les lignes de base du texte */
}

La propriété Flex expliquée

La propriété flex est un raccourci pour trois propriétés : flex-grow, flex-shrink et flex-basis. Les comprendre individuellement vous aide à écrire des mises en page plus précises.

.item-grow {
  flex: 1;        /* Équivalent à : 1 1 0% */
}

.item-fixed {
  flex: 0 0 200px; /* Ne pas grandir ou rétrécir, rester à 200px */
}

.item-shrink {
  flex: 0 1 auto;  /* Ne pas grandir, mais peut rétrécir si nécessaire */
}

Conseil de pro : Utilisez flex: 1 lorsque vous voulez que les éléments partagent l'espace de manière égale, et flex: 0 0 auto lorsque vous voulez que les éléments conservent leur taille naturelle sans grandir ou rétrécir.

Les bases de Grid (mise en page 2D)

CSS Grid est conçu pour les mises en page bidimensionnelles — contrôler simultanément les lignes et les colonnes. C'est le choix privilégié pour les mises en page de pages, les grilles de cartes et tout design où vous avez besoin d'un contrôle précis sur les deux dimensions.

Concepts de base

Les mises en page Grid se composent d'un conteneur de grille et d'éléments de grille. Contrairement à Flexbox, Grid vous permet de définir des pistes explicites (lignes et colonnes) et de placer les éléments n'importe où dans cette structure :

/* Le conteneur de grille */
.container {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;  /* 3 colonnes */
  grid-template-rows: auto 1fr auto;     /* 3 lignes */
  gap: 1rem;                             /* Espace entre les cellules */
  grid-auto-flow: row;                   /* Comment les éléments auto-placés s'écoulent */
}

/* Éléments de grille */
.item {
  grid-column: 1 / 3;    /* S'étendre de la ligne de colonne 1 à 3 */
  grid-row: 1 / 2;       /* Occuper la première ligne */
}

.item-area {
  grid-area: header;     /* Placer dans la zone nommée */
}

Comprendre les lignes et pistes de grille

Grid crée des lignes numérotées entre les pistes. Une grille à 3 colonnes a 4 lignes verticales (1, 2, 3, 4). Les éléments sont placés en spécifiant entre quelles lignes ils s'étendent.

Les pistes sont les espaces entre les lignes — vos colonnes et lignes réelles. Vous pouvez les dimensionner avec des unités fixes (px), des unités flexibles (fr) ou un dimensionnement basé sur le contenu (auto, min-content, max-content).

L'unité FR

L'unité fr est le super pouvoir de Grid. Elle représente une fraction de l'espace disponible, le distribuant proportionnellement entre les pistes :

.container {
  grid-template-columns: 1fr 2fr 1fr;  /* La colonne du milieu obtient 2x l'espace */
  grid-template-columns: 200px 1fr;    /* Barre latérale fixe, contenu flexible */
  grid-template-columns: repeat(3, 1fr); /* Trois colonnes égales */
}

Zones de grille nommées

La fonctionnalité des zones de modèle de Grid vous permet de créer des mises en page en utilisant une syntaxe semblable à de l'art ASCII, rendant les mises en page complexes lisibles :

.container {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar content content"
    "footer footer footer";
  grid-template-columns: 200px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }

Placement automatique et flux automatique de grille

Grid peut placer automatiquement les éléments que vous ne positionnez pas explicitement. La propriété grid-auto-flow contrôle si les éléments remplissent d'abord les lignes (par défaut) ou les colonnes en premier :

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: dense;  /* Remplir les espaces avec des éléments plus petits */
}

Conseil de pro : Utilisez grid-auto-flow: dense pour des mises en page de type maçonnerie où vous voulez remplir les espaces, mais sachez que cela peut changer l'ordre visuel des éléments, affectant potentiellement l'accessibilité.

Comparaison côte à côte

Comparons Flexbox et Grid sur des dimensions clés pour comprendre leurs différences fondamentales :

Fonctionnalité Flexbox Grid
Dimensionnalité Unidimensionnel (ligne OU colonne) Bidimensionnel (lignes ET colonnes)
Piloté par le contenu Oui - les éléments contrôlent leur taille Non - le conteneur définit la structure
Direction de mise en page Un seul axe à la fois Les deux axes simultanément
Placement des éléments Séquentiel (ordre source) Positionnement explicite possible
Alignement Puissant sur un seul axe Puissant sur les deux axes
Support des espaces Oui (navigateurs modernes) Oui (dès le début)
Idéal pour Composants, navigation, barres d'outils Mises en page de pages, grilles de cartes, tableaux de bord
Courbe d'apprentissage Modérée Plus raide initialement

Différences conceptuelles

La différence fondamentale se résume au contrôle. Flexbox est du contenu vers l'extérieur — les éléments influencent la mise en page en fonction de leur taille de contenu. Grid est de la mise en page vers l'intérieur — vous définissez d'abord la structure, puis vous y placez le contenu.

Pensez à Flexbox comme une règle flexible qui s'ajuste à ce que vous mesurez. Grid ressemble plus à du papier millimétré où vous décidez de la structure à l'avance.

Scénario Approche Flexbox Approche Grid
Barre de navigation Adapté naturellement - éléments en ligne Excessif - trop de structure
Grille de cartes Possible mais enroulement maladroit Parfait - lignes et colonnes explicites
Mise en page de formulaire Bon pour les formulaires simples Meilleur pour les formulaires complexes multi-colonnes
Mise en page de page Nécessite l'imbrication de plusieurs conteneurs Un seul conteneur peut le gérer
Centrage du contenu Excellent - simple et intuitif Également excellent - place-items: center

Quand utiliser Flexbox

Flexbox brille dans les scénarios où le contenu s'écoule dans une seule direction et où les éléments doivent s'adapter à l'espace disponible. Voici les situations où Flexbox est votre meilleur choix :

Barres de navigation et menus

Les composants de navigation sont l'exemple type de Flexbox. Les éléments s'écoulent naturellement en ligne, et vous voulez souvent qu'ils distribuent l'espace uniformément ou s'alignent aux extrémités opposées :

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
}

.nav-links {
  display: flex;
  gap: 2rem;
  list-style: none;
}

Groupes de boutons et barres d'outils

Lorsque vous avez une collection de boutons ou d'outils qui doivent être côte à côte, Flexbox gère parfaitement l'espacement et l'alignement :

.button-group {
  display: flex;
  gap: 0.5rem;
}

.toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 1rem;
}

Objets média

Le modèle classique d'objet média (image d'un côté, contenu de l'autre) est trivial avec Flexbox :

.media {
  display: flex;
  gap: 1rem;
}

.media-image {
  flex: 0 0 100px;  /* Image de largeur fixe */
}

.media-content {
  flex: 1;  /* Le contenu prend l'espace restant */
}

Contrôles de formulaire

Les groupes d'entrée où une étiquette, une entrée et un bouton sont en ligne sont parfaits pour Flexbox :

.input-group {
  display: flex;
  gap: 0.5rem;
}

.input-group input {
  flex: 1;  /* L'entrée grandit pour remplir l'espace */
}

.input-group button {
  flex: 0 0 auto;  /* Le bouton reste à sa taille naturelle */
}

Centrage vertical