Le CSS a cette particularité qu'on peut le pratiquer pendant des mois en obtenant des résultats corrects sans jamais avoir de modèle mental de ce qui se passe. Une div ne se centre pas, on ajoute display: flex, puis justify-content: center, ça ne bouge pas, on tente align-items: center, ça marche. On garde les deux au cas où, et on passe à la suite.
Cette méthode fonctionne un temps. Elle casse le jour où la maquette devient un peu dense, où un élément doit rester collé en bas d'une carte pendant que les autres cartes ont des hauteurs différentes, ou quand une grille de produits doit se réorganiser sans qu'on écrive dix media queries.
Flexbox et Grid ne sont pas deux versions du même outil, l'un moderne et l'autre plus moderne. Ce sont deux modèles de disposition qui répondent à deux questions différentes, et la plupart des blocages viennent d'avoir choisi celui qui ne correspondait pas à la question posée. Ce qui suit vise à te faire choisir avant d'écrire, pas après trois essais.
Le cycle du tâtonnement
Voici la forme que ça prend en pratique, sur une carte produit tout à fait banale. Titre, description de longueur variable, prix, bouton. La demande est simple : les boutons doivent s'aligner sur la même ligne en bas de chaque carte, même quand une description fait deux lignes et la suivante cinq.
La séquence habituelle commence par une hauteur fixe sur les cartes, ce qui tronque le texte le plus long. On passe à position: absolute sur le bouton, ce qui règle le problème visuellement et en crée un autre au premier redimensionnement. Puis on cherche sur Stack Overflow, on copie un bloc de dix lignes qui fonctionne, et on ne saura pas le reproduire la semaine suivante sur un cas voisin.
La réponse tient en une propriété appliquée au bon élément. Elle sera donnée plus bas, mais elle ne sert à rien tant que le raisonnement qui y mène n'est pas en place. Un extrait de code recopié règle un cas ; un modèle mental règle la famille de cas.
La question qui tranche entre Flexbox et Grid
Une seule question suffit à choisir dans la grande majorité des situations :
Dans le premier cas, c'est Flexbox. Le conteneur distribue l'espace disponible entre des éléments qui gardent leur mot à dire sur leur taille. Une barre de navigation, une liste de tags, un groupe de boutons, une ligne avec un logo à gauche et un menu à droite : le nombre d'éléments peut changer sans que le CSS bouge.
Dans le second, c'est Grid. Tu décris d'abord la structure, colonnes et lignes, puis tu y déposes le contenu. Une mise en page de page complète avec en-tête, barre latérale, contenu principal et pied de page, ou une galerie où toutes les vignettes doivent s'aligner en colonnes strictes : la trame existe indépendamment de ce qu'on met dedans.
Une autre formulation aide beaucoup les personnes en reconversion à qui j'enseigne le CSS : avec Flexbox, le contenu commande ; avec Grid, le conteneur commande. Quand tu hésites, demande-toi qui doit avoir le dernier mot sur les dimensions.
Les deux modèles cohabitent sans problème dans une même page. Un layout Grid pour la structure générale, et à l'intérieur d'une cellule, un conteneur Flexbox pour aligner trois boutons : c'est la combinaison la plus courante sur un site réel, pas un compromis bancal.
Les deux axes, la source de la moitié des confusions
Pourquoi justify-content déplace parfois horizontalement, parfois verticalement ? Parce que ces propriétés ne parlent ni de gauche ni de haut. Elles parlent d'axes, et l'orientation des axes dépend d'une autre propriété.
Un conteneur flex a un axe principal, défini par flex-direction. Par défaut il vaut row, donc l'axe principal est horizontal. L'axe transversal est perpendiculaire, donc vertical. Passe en flex-direction: column et les deux axes pivotent, ce qui inverse le comportement des mêmes propriétés sans que tu les aies touchées.
La règle à retenir
justify-*agit sur l'axe principalalign-*agit sur l'axe transversal
En Grid, ces mêmes préfixes existent mais les axes ne bougent pas : justify-* concerne toujours les colonnes, align-* toujours les lignes. Et le suffixe indique la cible : -content déplace l'ensemble des pistes dans le conteneur, -items déplace chaque élément dans sa cellule, -self déplace un élément précis. Six propriétés, deux dimensions à combiner, plus rien à mémoriser au hasard.
Quatre mises en page, quatre décisions
La barre de navigation avec logo à gauche et menu à droite
Les éléments se suivent sur une ligne, leur largeur dépend de leur contenu. Flexbox.
.navbar {
display: flex;
align-items: center; /* alignement vertical, axe transversal */
justify-content: space-between;
gap: 16px;
}
Aucune largeur n'est écrite. Ajoute un troisième bloc dans la barre, le CSS tient toujours.
La carte dont le bouton reste collé en bas
Le cas ouvert plus haut. La carte devient un conteneur flex en colonne, et une marge automatique absorbe tout l'espace restant au-dessus du bouton.
.card {
display: flex;
flex-direction: column;
height: 100%;
}
.card__button {
margin-top: auto;
}
Deux lignes utiles. En Flexbox, une marge auto mange l'espace libre de son côté, et cette mécanique remplace la plupart des positionnements absolus qu'on voit dans les projets de débutants.
La grille de cartes qui s'adapte sans media query
Une trame de colonnes régulières, avec un nombre de colonnes qui dépend de la place disponible. Grid, et un seul déclaration fait le travail.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
Le navigateur calcule combien de colonnes de 280 pixels minimum tiennent dans la largeur, puis répartit le surplus grâce à 1fr. Quatre colonnes sur un écran large, une seule sur mobile, sans point de rupture écrit à la main.
La variante auto-fit se comporte pareil sauf quand il reste des colonnes vides : auto-fit les écrase et laisse le contenu s'étirer, auto-fill les conserve. Avec trois cartes sur un grand écran, auto-fit donne trois cartes très larges, auto-fill garde des cartes de taille normale alignées à gauche.
La structure de page en zones nommées
Ici la trame préexiste au contenu, et Grid permet de la dessiner en toutes lettres dans le CSS.
.layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"aside main"
"footer footer";
min-height: 100vh;
}
.layout > header { grid-area: header; }
.layout > aside { grid-area: aside; }
.layout > main { grid-area: main; }
.layout > footer { grid-area: footer; }
@media (max-width: 720px) {
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"aside"
"footer";
}
}
La version mobile réordonne les zones sans toucher au HTML, et la barre latérale passe sous le contenu principal. Un détail à surveiller : cet écart entre l'ordre visuel et l'ordre du document se lit à la souris mais pas au clavier, puisque la tabulation suit le HTML. Sur un menu ou un formulaire, ça devient un problème d'accessibilité réel.
Les pièges qui font perdre des heures
Le texte qui refuse de se tronquer dans un conteneur flex
Un élément flex a par défaut min-width: auto, ce qui l'empêche de rétrécir en dessous de la largeur de son contenu. Résultat : un long titre pousse la carte hors du conteneur et text-overflow: ellipsis ne produit rien. Le correctif tient en une déclaration sur l'élément qui déborde : min-width: 0. Sur les projets que je reprends en dépannage, c'est de loin la ligne de CSS que j'ajoute le plus souvent.
Confondre width et flex-basis
Sur un élément flex, flex-basis prend le pas sur width quand l'axe principal est horizontal. Écrire les deux avec des valeurs différentes donne l'impression que la largeur est ignorée. Le raccourci flex: 1 vaut 1 1 0%, ce qui remet la base à zéro et fait que tous les éléments finissent à la même largeur, quel que soit leur contenu. Pour que le contenu reste pris en compte, la valeur est flex: 1 1 auto.
Utiliser Grid là où une ligne suffit
Une barre d'outils avec un nombre variable de boutons en Grid oblige à recompter les colonnes à chaque ajout. Le même besoin en Flexbox n'a rien à recompter. Cette erreur n'empêche rien de fonctionner, elle produit du CSS qu'il faut modifier à chaque évolution.
Attendre une hauteur qui n'existe pas
height: 100% demande à un élément d'occuper toute la hauteur de son parent, ce qui suppose que le parent en ait une définie. Si la chaîne est interrompue quelque part au-dessus, la valeur est ignorée en silence. Les unités 100vh ou 100dvh contournent le problème en se référant à la fenêtre, et dvh tient compte de la barre d'adresse qui se replie sur mobile.
Empiler des marges au lieu d'utiliser gap
La propriété gap fonctionne en Flexbox comme en Grid sur tous les navigateurs courants depuis plusieurs années. Les astuces à base de marge négative sur le conteneur pour compenser la marge du dernier élément appartiennent à une époque révolue, et elles cassent dès qu'un élément passe à la ligne.
Le réflexe qui règle la plupart de ces cas se prend avec les outils du navigateur. Dans l'inspecteur de Chrome ou Firefox, un badge flex ou grid apparaît à côté du conteneur ; en cliquant dessus, tu obtiens la visualisation des pistes, des numéros de ligne et des zones libres. Cette étape transforme le débogage CSS en lecture au lieu d'un jeu de devinettes, et elle rejoint ce qui est décrit dans l'article sur la méthode pour débugger sans paniquer.
Aller plus loin sur les bases
Ces mécaniques s'installent beaucoup plus vite en construisant des pages complètes qu'en lisant de la documentation. La formation HTML et CSS : créer sa première page web couvre la structure sémantique, le modèle de boîte, Flexbox et Grid sur des mises en page réelles. Elle fait partie de la catégorie Fondamentaux du catalogue LaPolaris, qui sert de socle avant d'attaquer un framework.
Un dernier point qui revient souvent chez les personnes en reconversion et les développeurs juniors : le CSS mis en page correctement ne remplace pas un HTML correct. Une grille visuellement impeccable construite sur une pile de div sans balises sémantiques reste difficile à naviguer au clavier et pauvre pour le référencement. Le choix entre Flexbox et Grid vient après la question de savoir ce que représente chaque bloc de la page.
Questions fréquentes
Faut-il apprendre Flexbox avant Grid ?
Grid remplace-t-il Flexbox ?
Comment centrer un élément horizontalement et verticalement ?
display: grid; place-items: center;. La propriété place-items combine align-items et justify-items en une déclaration. La version Flexbox demande display: flex; align-items: center; justify-content: center; et donne le même résultat. Dans les deux cas, le conteneur doit avoir une hauteur pour que le centrage vertical ait un sens.Est-ce que je peux abandonner Bootstrap grâce à Grid ?
Pourquoi mes colonnes ne font pas la largeur demandée ?
box-sizing: border-box appliqué globalement. Soit un contenu indivisible, image ou mot très long, impose un minimum, ce que règlent min-width: 0 sur l'élément et minmax(0, 1fr) sur la piste Grid.Combien de temps pour être à l'aise avec les deux ?
Une chose ne se règle pas avec un modèle mental : il faut avoir cassé quelques mises en page pour reconnaître les symptômes. Prends une page d'un site que tu aimes bien, ouvre l'inspecteur, et reconstruis-la sans regarder son CSS. Ce que tu n'arriveras pas à reproduire indiquera exactement ce qui te manque.
Pour la suite du parcours, l'article sur le choix entre front-end, back-end et fullstack aide à situer le CSS dans un parcours complet.