Flexbox est arrivé dans tous les principaux navigateurs vers 2015 et a immédiatement résolu le problème que les développeurs contournaient depuis une décennie : le centrage vertical. Mais la plupart des gens l'ont appris à l'envers — ils ont mémorisé justify-content: center depuis une fiche de référence sans comprendre pourquoi cela fonctionne. Quand la mise en page ne se comporte pas comme prévu, cette lacune transforme une tâche de cinq minutes en une heure de tâtonnements. Ce guide construit d'abord le modèle mental, puis couvre toutes les propriétés qui comptent vraiment dans des projets réels.

Le modèle mental : un axe à la fois

Le concept fondamental de Flexbox est qu'il dispose les éléments sur un seul axe. Il y a un axe principal — la direction dans laquelle les éléments s'écoulent — et un axe transversal, perpendiculaire au premier. L'insight crucial que presque tous les débutants manquent : flex-direction détermine quel axe est lequel. Tout le reste en découle.

css
/* Default: main axis runs LEFT → RIGHT, cross axis runs TOP → BOTTOM */
.container {
  display: flex;
  flex-direction: row; /* default */
}

/* Rotated: main axis now runs TOP → BOTTOM, cross axis runs LEFT → RIGHT */
.container {
  display: flex;
  flex-direction: column;
}

/*
  justify-content  →  controls alignment on the MAIN axis
  align-items      →  controls alignment on the CROSS axis

  This is why centering something in both axes looks like this:
*/
.center-both {
  display: flex;
  justify-content: center; /* horizontally centred (main axis = row) */
  align-items: center;     /* vertically centred (cross axis)        */
}
La confusion qui piège tout le monde : quand vous passez à flex-direction: column, justify-content ne contrôle plus l'alignement horizontal — il contrôle l'alignement vertical, car l'axe principal a pivoté. align-items contrôle maintenant l'horizontal. Gardez cette rotation en tête chaque fois qu'un élément ne s'aligne pas où vous l'attendez.

Propriétés du conteneur

Ces propriétés s'appliquent au conteneur flex — l'élément parent avec display: flex. Elles contrôlent la façon dont tous les éléments enfants sont distribués et alignés.

css
/* display: flex makes the element a block-level flex container.
   display: inline-flex makes it inline (sits in text flow). */
.nav {
  display: flex;
}

/* flex-direction — which way does the main axis run? */
.nav {
  flex-direction: row;         /* left to right (default)  */
  flex-direction: row-reverse; /* right to left            */
  flex-direction: column;      /* top to bottom            */
  flex-direction: column-reverse; /* bottom to top         */
}

/* flex-wrap — what happens when items overflow the container? */
.card-grid {
  flex-wrap: nowrap;       /* all items forced onto one line (default) */
  flex-wrap: wrap;         /* items wrap onto additional lines         */
  flex-wrap: wrap-reverse; /* items wrap in reverse order              */
}

/* gap — space between items. Modern approach; avoids margin hacks. */
.card-grid {
  gap: 1.5rem;             /* same in both directions              */
  gap: 1rem 2rem;          /* row-gap column-gap                   */
}

La propriété gap mérite une mention spéciale. Avant son existence, la pratique courante était d'ajouter des marges aux éléments flex puis de les annuler sur les bords extérieurs avec des marges négatives. gap remplace tout cela proprement — utilisez-la partout à la place.

css
/* justify-content — alignment on the MAIN axis */
.nav {
  justify-content: flex-start;    /* packed to start (default)              */
  justify-content: flex-end;      /* packed to end                          */
  justify-content: center;        /* packed to centre                       */
  justify-content: space-between; /* first/last at edges, equal gaps between */
  justify-content: space-around;  /* equal space around each item           */
  justify-content: space-evenly;  /* equal space between every gap          */
}

/* align-items — alignment on the CROSS axis (single line) */
.nav {
  align-items: stretch;   /* items fill cross-axis height (default)         */
  align-items: flex-start;/* items align to start of cross axis             */
  align-items: flex-end;  /* items align to end of cross axis               */
  align-items: center;    /* items centred on cross axis                    */
  align-items: baseline;  /* items aligned by their text baseline           */
}

/* align-content — cross-axis alignment when there are MULTIPLE lines
   (only takes effect with flex-wrap: wrap and enough items to wrap) */
.card-grid {
  flex-wrap: wrap;
  align-content: flex-start;    /* rows packed to top                       */
  align-content: center;        /* rows centred vertically                  */
  align-content: space-between; /* rows spread out with space between       */
}

Voici une vraie barre de navigation combinant tout cela. Le logo est à gauche, et les liens de navigation sont poussés à droite grâce à margin-left: auto — une astuce Flexbox classique. L'approche justify-content: space-between fonctionne aussi, mais la technique de la marge automatique est plus flexible quand vous avez plus de deux groupes.

css
/* Nav: logo left, links right */
.site-nav {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 2rem;
  height: 64px;
  background: #1a1a2e;
}

.site-nav .logo {
  font-size: 1.25rem;
  font-weight: 700;
  color: #fff;
  text-decoration: none;
}

.site-nav .nav-links {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  margin-left: auto; /* pushes everything after it to the right */
  list-style: none;
  margin-top: 0;
  margin-bottom: 0;
  padding: 0;
}

.site-nav .nav-links a {
  color: #ccc;
  text-decoration: none;
  font-size: 0.9rem;
}

.site-nav .nav-links a:hover {
  color: #fff;
}

Propriétés des éléments

Ces propriétés s'appliquent aux éléments flex — les enfants directs du conteneur flex. Elles contrôlent la façon dont les éléments individuels grandissent, rétrécissent et se dimensionnent.

  • flex-grow — quelle part de l'espace libre disponible cet élément réclame. Par défaut 0 (ne pas grandir). Défini à 1 sur un élément, il prend tout l'espace restant.
  • flex-shrink — de combien cet élément rétrécit par rapport aux autres quand l'espace est insuffisant. Par défaut 1. Défini à 0 pour empêcher un élément de rétrécir.
  • flex-basis — la taille initiale de l'élément avant tout agrandissement ou rétrécissement. Peut être une longueur (250px, 30%) ou auto (utiliser la taille du contenu de l'élément).
  • align-self — remplace align-items pour un élément spécifique. Accepte les mêmes valeurs : auto, flex-start, flex-end, center, baseline, stretch.
  • order — modifie l'ordre visuel sans toucher au HTML. Par défaut 0. Les valeurs plus basses apparaissent en premier. À utiliser avec parcimonie — cela brise l'ordre de tabulation et crée des problèmes d'accessibilité pour les utilisateurs de clavier et de lecteurs d'écran.
css
/* Classic sidebar + main content layout */
.app-layout {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  flex: 0 0 280px; /* don't grow, don't shrink, always 280px wide */
  background: #f5f5f5;
  padding: 2rem 1.5rem;
}

.main-content {
  flex: 1; /* grow to fill all remaining space */
  padding: 2rem;
  min-width: 0; /* critical: prevents content overflow in flex children */
}

/* Responsive: stack vertically on mobile */
@media (max-width: 768px) {
  .app-layout {
    flex-direction: column;
  }

  .sidebar {
    flex: none; /* reset — don't use flex-basis on column layout */
  }
}
Le piège de min-width: 0 : par défaut, les éléments flex ne peuvent pas rétrécir en dessous de leur taille minimale de contenu. Si vous avez un mot long ou un tableau large à l'intérieur d'un élément flex, il déborda plutôt que de se replier. Ajouter min-width: 0 à l'élément flex résout ce problème. Cela revient constamment avec la zone de contenu principale dans les mises en page à barre latérale.

La propriété raccourcie flex expliquée

La propriété raccourcie flex regroupe flex-grow, flex-shrink et flex-basis en une seule déclaration. La spécification W3C définit quelques valeurs de mots-clés qui couvrent les cas courants, et elles sont souvent confondues entre elles.

css
/* flex: 1
   Expands to: flex-grow: 1; flex-shrink: 1; flex-basis: 0%
   Meaning: grow and shrink freely; start from zero (ignore content size).
   All items with flex: 1 share space equally, regardless of content.
   Most common choice for "fill available space". */
.tab { flex: 1; }

/* flex: auto
   Expands to: flex-grow: 1; flex-shrink: 1; flex-basis: auto
   Meaning: grow and shrink freely; start from the item's content size.
   Items with more content get more space — proportional, not equal. */
.column { flex: auto; }

/* flex: none
   Expands to: flex-grow: 0; flex-shrink: 0; flex-basis: auto
   Meaning: completely rigid — don't grow, don't shrink, stay at content size.
   Use for items that should never flex (icons, avatars, fixed labels). */
.avatar { flex: none; }

/* flex: 0 0 200px
   Explicit: don't grow, don't shrink, always exactly 200px.
   Same as writing out all three values. More readable for fixed-size items. */
.sidebar { flex: 0 0 200px; }

/* Practical difference: flex: 1 vs flex: auto in a tab bar
   With flex: 1  → all tabs are equal width regardless of label length
   With flex: auto → "Settings" tab is wider than "Home" tab */
.tabs { display: flex; }
.tab-equal  { flex: 1;    } /* equal width tabs     */
.tab-auto   { flex: auto; } /* content-sized tabs   */

Mises en page réelles courantes

Voici quatre patrons que vous utiliserez régulièrement — construits uniquement avec Flexbox.

css
/* 1. Sticky footer
   The footer always sits at the bottom, even on short pages.
   body (or .app-shell) becomes a column flex container. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
}

main {
  flex: 1; /* expands to push footer down */
}

footer {
  /* stays at the bottom */
}
css
/* 2. Centred modal / hero content
   Both axes centred — the Flexbox vertical-centring party trick. */
.hero {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 2rem;
  background: linear-gradient(135deg, #667eea, #764ba2);
}

.hero-content {
  max-width: 640px;
  text-align: center;
  color: #fff;
}
css
/* 3. Nav bar: logo left, links right */
.site-nav {
  display: flex;
  align-items: center;
  padding: 0 2rem;
  height: 64px;
}

.site-nav .nav-links {
  margin-left: auto; /* auto margin consumes all free space to its left */
  display: flex;
  gap: 1.5rem;
  list-style: none;
  padding: 0;
  margin-top: 0;
  margin-bottom: 0;
}
css
/* 4. Card row that wraps on mobile */
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}

.card {
  flex: 1 1 280px; /* grow and shrink, but never below 280px wide */
  background: #fff;
  border-radius: 8px;
  padding: 1.5rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

/* On wide screens: 3-4 cards per row.
   On narrow screens: cards wrap into their own rows automatically.
   No media query needed for the wrap itself — flex-wrap handles it. */

Flexbox vs Grid — quand utiliser lequel

Cette question revient constamment, et la réponse est plus simple que la plupart des articles ne le font paraître : Flexbox est pour les mises en page unidimensionnelles. CSS Grid est pour les mises en page bidimensionnelles. Si vous disposez des éléments sur une seule ligne ou une seule colonne — une barre de navigation, un groupe de boutons, une rangée de cartes — Flexbox est le bon outil. Si vous devez contrôler à la fois les lignes et les colonnes simultanément — une mise en page de page complète, une mosaïque de photos, une grille de formulaire — optez plutôt pour Grid.

En pratique, vous utiliserez les deux dans le même projet. Grid gère la structure au niveau de la page (en-tête, barre latérale, contenu principal, pied de page). Flexbox gère les composants dans ces régions (la barre de navigation, le contenu de la carte, le groupe de boutons dans une fenêtre modale). Ils se complètent plutôt qu'ils ne se font concurrence.

La zone grise : les grilles de cartes qui doivent avoir des lignes de hauteur égale avec des éléments alignés en colonnes. Flexbox avec flex-wrap: wrap peut le faire, mais les éléments dans la même ligne visuelle n'ont aucune relation entre eux — leurs hauteurs sont indépendantes. Le dimensionnement implicite des lignes de Grid gère cela automatiquement. Si vous avez besoin que les cartes d'une ligne enveloppée aient toutes la même hauteur ET que leurs éléments internes s'alignent d'une carte à l'autre, Grid est plus propre.

Conclusion

Le modèle mental de Flexbox est le suivant : choisissez une direction, comprenez quelles propriétés contrôlent quel axe, puis décidez si les éléments doivent grandir, rétrécir ou rester fixes. Une fois que ça clique, la fiche de référence devient un outil de consultation — et non une béquille. Le guide Flexbox de MDN est la meilleure référence pour les cas limites, et le guide complet CSS-Tricks reste la fiche de référence visuelle la plus utile. Pour une utilisation en production, la prise en charge par les navigateurs est essentiellement universelle — aucun préfixe nécessaire. La spécification W3C vaut la peine d'être parcourue si vous rencontrez un cas limite vraiment déroutant — l'algorithme est documenté avec précision et répond à la plupart des questions « pourquoi ça se comporte ainsi ».