Retour au cours

frontend / css

Flexbox avancé

Leçon 61 exercice

Explication

Ce que vous allez apprendre

  • Comprendre pourquoi flex-basis prime sur width dans un conteneur flex
  • Résoudre le piège classique du texte qui déborde avec min-width: 0
  • Distinguer flex: 1 1 0 de flex: 1 1 auto
  • Construire un sticky footer sans JavaScript avec Flexbox
  • Créer des cartes de largeur égale qui passent à la ligne automatiquement

Dans quel contexte ?

Sur messagerie.html, le nom de l'expéditeur d'un message pousse le contenu du message hors de sa carte au lieu de se tronquer avec des points de suspension, malgré un text-overflow: ellipsis déjà en place. Le coupable : l'élément flex, par défaut, refuse de rétrécir sous la taille naturelle de son contenu texte. Ajouter min-width: 0 sur cet élément débloque enfin la troncature, un correctif quasi systématique dès qu'on combine Flexbox et texte tronqué.

Étape 1 : de la théorie à la pratique

La leçon précédente a posé les bases de Flexbox : axes, alignement, flex: 1. Sur un vrai projet, des subtilités apparaissent vite — un élément qui refuse de rétrécir, un texte qui déborde sans raison apparente.

Étape 2 : le piège de width sur un élément flex

D'abord, un piège fréquent : définir width: 300px sur un élément flex en espérant qu'il fasse exactement 300px. En Flexbox, ce n'est pas width qui décide en premier.

Étape 3 : qui décide vraiment de la taille de départ

C'est flex-basis qui détermine la taille de départ avant redistribution de l'espace — width est simplement ignoré tant que flex-basis n'est pas explicitement auto. Comprendre cette priorité évite beaucoup de surprises.

DéclarationComportement
width: 300px seul (sans flex-basis)Ignoré : flex-basis: auto par défaut se base sur le contenu
flex-basis: 200pxPrime sur width, sert de taille de départ réelle
flex: 1 1 0Ignore le contenu, distribue l'espace à égalité stricte
flex: 1 1 autoPart de la taille du contenu, distribue seulement le surplus

Étape 4 : le correctif le plus sous-estimé

Il reste un comportement qui piège presque tous les développeurs au moins une fois : par défaut, un élément flex refuse de rétrécir en dessous de la taille de SON CONTENU, même avec flex-shrink: 1. Un texte long fait alors déborder toute la mise en page au lieu de se tronquer proprement.

Étape 5 : la solution, min-width: 0

Voici comment on corrige ça : min-width: 0 autorise enfin l'élément à rétrécir réellement. C'est un correctif quasi systématique dès qu'on combine Flexbox et texte tronqué avec text-overflow: ellipsis.

Piège fréquent

Un enfant flex a une min-width implicite de auto, ce qui l'empêche de rétrécir sous la taille de son contenu même avec flex-shrink: 1 et overflow: hidden. Ajoutez systématiquement min-width: 0 (ou min-height: 0 en colonne) dès que vous combinez Flexbox et troncature de texte.

Une fois ces pièges évités, voyons un pattern très utile : pousser un pied de page tout en bas de l'écran, même quand le contenu est court. La solution consiste à rendre la page entière flex en colonne avec une hauteur minimale de 100vh, puis à donner flex: 1 à la zone de contenu — elle absorbe automatiquement l'espace vide restant.

Et ensuite ?

Une fois Flexbox maîtrisé sur un seul axe, la prochaine étape consiste à passer à deux dimensions à la fois avec CSS Grid.

Commandes & code

Flexbox avancé

Les cas réels où Flexbox devient subtil : calcul de taille, imbrication, patterns responsive.

css
/* Comprendre flex-basis vs width : flex-basis est prioritaire sur width en flex row */
.item {
    width: 300px;       /* ignoré tant que flex-basis n'est pas "auto" */
    flex-basis: 200px;  /* c'est CETTE valeur qui sert de point de départ */
}

/* flex-basis: 0 vs auto : la nuance qui piège le plus */
.item-a { flex: 1 1 0; }    /* ignore le contenu, distribue l'espace À ÉGALITÉ stricte */
.item-b { flex: 1 1 auto; } /* part de la taille du CONTENU, puis distribue le surplus */
css
/* Pattern : cartes de largeur égale, wrap responsive, sans media query */
.grille-cartes {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
}
.carte {
    flex: 1 1 280px;
    /* grandit pour remplir, rétrécit si besoin, jamais sous 280px
       -> le nombre de colonnes s'adapte automatiquement à la largeur dispo */
    min-width: 0; /* évite qu'un contenu (image, texte long) ne force un débordement */
}
css
/* Pattern : sticky footer avec Flexbox */
.page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
.contenu {
    flex: 1; /* pousse le footer en bas même si le contenu est court */
}
css
/* Pattern : barre d'outils avec un item qui absorbe tout l'espace restant */
.toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
}
.toolbar .titre {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap; /* le titre se tronque, les boutons gardent leur taille */
}
css
/* Flexbox imbriqué : un conteneur flex peut être un item flex de son parent */
.layout {
    display: flex;
    gap: 24px;
}
.sidebar { flex: 0 0 240px; }
.contenu-principal {
    flex: 1;
    display: flex;       /* devient lui-même un conteneur flex */
    flex-direction: column;
    gap: 16px;
}
css
/* min-width: 0 / min-height: 0 : le correctif le plus sous-estimé de Flexbox */
/* Par défaut, un flex item a min-width: auto -> il refuse de rétrécir sous
   la taille de son contenu (texte non cassable, image...) -> débordement possible */
.item-avec-long-texte {
    flex: 1;
    min-width: 0; /* autorise enfin le rétrécissement, à combiner avec overflow/ellipsis */
}

Résumé

  • flex-basis prime sur width en flex-direction: row tant qu'il n'est pas auto.
  • flex: 1 1 0 ignore la taille du contenu, flex: 1 1 auto en tient compte.
  • min-width: 0 est le correctif indispensable contre les débordements de texte/image en Flexbox.
  • Un conteneur flex peut librement être imbriqué comme item flex d'un autre.

Exercices pratiques

1 disponible
1

Mission : une messagerie où le texte fait exploser la mise en page

Objectif : Diagnostiquer un conflit flex-basis / width et une troncature bloquée, puis livrer la correction précise.

Contexte

Sur messagerie.css, chaque message a une carte .message en display: flex avec deux enfants : .avatar (flex: 0 0 48px;) et .contenu (width: 300px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;). Le développeur pensait fixer .contenu à exactement 300px, mais le nom d'expéditeur très long pousse toute la carte à s'élargir bien au-delà, sans jamais se tronquer.

Résoudre l’exercice →