CSS Flexbox : Construire n'importe quelle mise en page en quelques minutes avec un générateur visuel
📷 Sai Kiran Anagani / PexelsCSS Flexbox : Construire n'importe quelle mise en page en quelques minutes avec un générateur visuel
flex-direction, justify-content, align-items — voyez exactement ce que chaque propriété fait avec un playground visuel en direct. Inclut des recettes de mise en page courantes.
Mon parcours avec Flexbox (et pourquoi je cherche encore)
Je me souviens exactement du moment où j'ai pensé comprendre flexbox. J'avais passé l'essentiel d'un après-midi à me battre avec une barre de navigation, les flottants ne faisaient pas ce que je voulais, inline-block ajoutait des espaces fantômes, et quelqu'un dans un commentaire Stack Overflow a dit "utilisez juste flexbox." Donc je l'ai fait. J'ai tapé display: flex et tout s'est aligné. Magique.
Le lendemain, j'ai essayé de centrer quelque chose verticalement et j'étais complètement perdu à nouveau.
C'est la particularité de flexbox — le point d'entrée semble facile, mais le modèle mental prend du temps à vraiment s'installer. Le moment où ça a finalement cliqué pour moi, c'est quand j'ai arrêté de penser en termes de "gauche, droite, haut, bas" et commencé à penser en termes d'axes. Une fois ce changement opéré, flexbox est devenu l'un des outils les plus satisfaisants en CSS.
Si vous voulez expérimenter visuellement en lisant, consultez le Générateur CSS Flexbox sur ToolBox Hubs — il vous permet de modifier les propriétés et de voir le résultat en temps réel, ce qui est honnêtement la façon la plus rapide de construire le modèle mental.
Le modèle de conteneur flex
Tout dans flexbox commence par une règle : vous avez un conteneur et des éléments à l'intérieur. Vous définissez display: flex sur le conteneur, et les enfants directs deviennent des éléments flex. C'est toute la hiérarchie — conteneur et éléments.
.container {
display: flex;
}
Cette seule ligne change beaucoup. Vos éléments seront maintenant en ligne par défaut, ils s'étireront pour remplir la hauteur du conteneur, et ils rétréciront si l'espace est insuffisant. La plupart des propriétés flexbox sont définies sur le conteneur, pas sur les éléments.
Les deux axes
C'est la partie qui déroute presque tout le monde qui apprend flexbox, et je dirais que c'est le concept le plus important à intérioriser. Flexbox fonctionne sur deux axes :
- Axe principal — la direction dans laquelle vos éléments s'écoulent (ligne ou colonne)
- Axe transversal — perpendiculaire à l'axe principal
Quand flex-direction est row (défaut), l'axe principal va de gauche à droite, et l'axe transversal de haut en bas. Quand vous passez à column, ceux-ci s'inversent. C'est important car justify-content et align-items sont définis relativement à ces axes, pas par rapport aux directions absolues.
Une fois que vous vous souvenez que justify signifie toujours "le long de l'axe principal" et align signifie toujours "le long de l'axe transversal", tout le reste devient prévisible.
Toutes les propriétés dont vous avez vraiment besoin
flex-direction
Contrôle la direction dans laquelle vos éléments s'écoulent.
.container {
display: flex;
flex-direction: row; /* défaut — de gauche à droite */
flex-direction: row-reverse; /* de droite à gauche */
flex-direction: column; /* de haut en bas */
flex-direction: column-reverse; /* de bas en haut */
}
column est quelque chose que j'utilise plus souvent que prévu. Chaque fois que vous voulez empiler des éléments verticalement et contrôler leur espacement, flex-direction: column combiné avec gap est fantastique.
justify-content
Aligne les éléments le long de l'axe principal. En ligne, c'est horizontal. En colonne, c'est vertical.
.container {
display: flex;
justify-content: flex-start; /* défaut — éléments au début */
justify-content: flex-end; /* éléments à la fin */
justify-content: center; /* éléments au milieu */
justify-content: space-between; /* espace égal entre les éléments, aucun sur les bords */
justify-content: space-around; /* espace égal autour de chaque élément */
justify-content: space-evenly; /* espace vraiment égal partout */
}
space-between est celui que j'utilise le plus pour les barres de navigation — les éléments se répartissent aux deux extrémités avec des espaces égaux entre eux. center est ce que vous voulez quand vous avez juste besoin que quelque chose soit au milieu.
align-items
Aligne les éléments le long de l'axe transversal. En ligne, c'est vertical. En colonne, c'est horizontal.
.container {
display: flex;
align-items: stretch; /* défaut — les éléments s'étirent pour remplir la hauteur du conteneur */
align-items: flex-start; /* les éléments sont en haut */
align-items: flex-end; /* les éléments sont en bas */
align-items: center; /* les éléments sont centrés verticalement */
align-items: baseline; /* les éléments sont alignés par leur ligne de base du texte */
}
stretch comme valeur par défaut est en fait assez utile — c'est pourquoi les éléments flex dans une ligne ont tous la même hauteur, même avec des quantités de contenu différentes. Mais dès que vous voulez centrer verticalement, vous atteignez align-items: center.
flex-wrap
Par défaut, les éléments flex essaient de tenir sur une ligne et rétrécissent pour y parvenir. flex-wrap vous permet de changer ce comportement.
.container {
display: flex;
flex-wrap: nowrap; /* défaut — les éléments restent sur une ligne */
flex-wrap: wrap; /* les éléments passent à de nouvelles lignes */
flex-wrap: wrap-reverse; /* les éléments passent vers le haut */
}
flex-wrap: wrap est essentiel pour les grilles de cartes responsives. Sans cela, vos éléments continueront à rétrécir quelle que soit la taille du viewport.
gap
gap n'est techniquement pas une propriété flex-only — elle vient de CSS Grid — mais elle fonctionne avec flexbox et elle est vraiment excellente. Avant gap, on faisait des hacks de margin. Maintenant :
.container {
display: flex;
gap: 16px; /* même écart dans les deux directions */
gap: 12px 24px; /* écart-ligne écart-colonne */
}
Utilisez-la partout. C'est plus simple que la margin et n'ajoute pas d'espace aux bords.
align-content
Celle-ci est facile à manquer. align-content est comme justify-content mais pour l'axe transversal, et elle ne fait quelque chose que lorsque vous avez plusieurs lignes (c'est-à-dire quand flex-wrap: wrap est en jeu et que les éléments ont effectivement enroulé). Si tous vos éléments sont sur une ligne, align-content n'a aucun effet visible.
.container {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
align-content: center;
align-content: space-between;
}
C'est probablement la propriété flexbox la plus souvent mal comprise — les gens la définissent en attendant quelque chose et rien ne se passe, parce que leurs éléments ne s'enroulent pas.
Propriétés au niveau de l'élément
Quelques propriétés vont sur les éléments flex eux-mêmes plutôt que sur le conteneur.
flex-grow — combien un élément grandit pour remplir l'espace disponible (défaut : 0)
flex-shrink — combien un élément rétrécit quand l'espace est serré (défaut : 1)
flex-basis — la taille de départ de l'élément avant de grandir ou rétrécir (défaut : auto)
Ces trois sont souvent combinés avec le raccourci flex :
.item {
flex: 1; /* grow: 1, shrink: 1, basis: 0 — éléments de largeur égale */
flex: 0 0 200px; /* largeur fixe, pas de croissance ou rétrécissement */
flex: 2; /* cet élément grandit deux fois plus vite que les frères flex: 1 */
}
align-self permet à un seul élément de remplacer le paramètre align-items du conteneur :
.special-item {
align-self: flex-end; /* cet élément reste en bas même si ses frères ne le font pas */
}
Modèles courants
Centrer n'importe quoi (le classique)
C'est probablement l'extrait CSS le plus googleé de l'histoire. Centrer un div à la fois horizontalement et verticalement :
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh; /* a besoin d'une hauteur pour centrer verticalement */
}
C'est tout. Deux lignes (trois si vous comptez la hauteur). Avant flexbox, le centrage vertical était vraiment pénible. Maintenant c'est un réflexe.
Barre de navigation responsive
Une navigation horizontale qui pousse le logo à gauche et les liens de navigation à droite :
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
}
Et pour le mobile, vous pourriez passer à la colonne :
@media (max-width: 768px) {
.navbar {
flex-direction: column;
gap: 12px;
}
}
Grille de cartes responsive
Des cartes côte à côte sur desktop qui s'empilent sur mobile :
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.card {
flex: 1 1 300px; /* grandir, rétrécir, largeur min de 300px */
max-width: 400px;
}
Le flex: 1 1 300px est la clé — il dit "commencer à 300px de large, mais grandir et rétrécir selon les besoins." Les cartes reflueront naturellement en moins de colonnes sur les petits écrans sans une seule media query.
Pied de page collant
Le classique "le pied de page reste en bas même avec peu de contenu" :
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1; /* le contenu principal grandit pour pousser le pied de page vers le bas */
}
footer {
/* reste en bas */
}
Celui-là est dans presque tous les projets que je construis.
Flexbox vs CSS Grid : Quand utiliser lequel
Il y a beaucoup de débat inutile à ce sujet en ligne. La réponse honnête est : utilisez les deux, ils sont pour des choses différentes.
Choisissez Flexbox quand :
- Vous avez une seule ligne ou colonne d'éléments
- Vous voulez que les éléments s'enroulent naturellement (comme des étiquettes, des listes de cartes)
- Vous construisez une barre de navigation, une toolbar, ou un groupe de boutons
- Vous avez besoin d'un axe de contrôle avec un dimensionnement d'éléments flexible
Choisissez CSS Grid quand :
- Vous avez une mise en page bidimensionnelle avec des lignes et des colonnes
- Vous construisez une mise en page au niveau de la page avec en-tête, sidebar, principal, pied de page
- Vous voulez le placement explicite des éléments dans des cellules spécifiques
- Vous avez besoin de hauteurs de ligne cohérentes sur plusieurs colonnes
En pratique, une vraie page pourrait utiliser Grid pour la mise en page globale, Flexbox pour la navigation, Flexbox pour la mise en page interne d'une carte, et Grid à nouveau pour un tableau de données. Ils se complètent bien.
Erreurs courantes et pièges
flex-shrink: 0 pour les images
Par défaut, les éléments flex peuvent rétrécir. Les images dans les conteneurs flex rétréciront en dessous de leur taille naturelle, ce qui est horrible. Corrigez-le :
img {
flex-shrink: 0;
}
Ou utilisez le raccourci :
img {
flex: 0 0 auto; /* ne pas grandir, ne pas rétrécir, utiliser la taille naturelle */
}
Le problème de débordement min-width: 0
Celui-ci est subtil et rend les gens fous. Par défaut, les éléments flex ont min-width: auto, ce qui signifie qu'ils ne rétréciront pas en dessous de leur taille de contenu. Si vous avez un élément flex contenant du texte long ou un élément large, il peut déborder de son conteneur même quand flex: 1 est défini.
La solution :
.flex-item {
min-width: 0; /* permettre à l'élément de rétrécir en dessous de la taille du contenu */
overflow: hidden; /* ou overflow: auto si vous voulez un défilement */
}
align-content ne fonctionne qu'avec l'enroulement
Comme mentionné ci-dessus, définir align-content sur un conteneur flex à une seule ligne ne fait absolument rien. Vous avez besoin de :
flex-wrap: wrapsur le conteneur- Assez d'éléments pour réellement s'enrouler sur plusieurs lignes
margin: auto est puissant dans les conteneurs flex
C'est plus une arme secrète qu'un piège, mais cela surprend les gens : définir margin-left: auto sur un élément flex le poussera (et tout ce qui suit) vers l'extrémité distante du conteneur. C'est ainsi que vous pouvez faire des mises en page de navigation avec un logo à gauche et un bouton de connexion tout à droite sans éléments d'enroulement :
.nav {
display: flex;
align-items: center;
}
.nav-login {
margin-left: auto; /* pousse le bouton de connexion vers le bord droit */
}
Construire des mises en page visuellement
Lire sur les propriétés flexbox est utile, mais la façon la plus rapide d'vraiment intérioriser le modèle mental est de jouer avec. Le Générateur CSS Flexbox vous permet de basculer chaque propriété et de voir la mise en page se mettre à jour en temps réel.
Sérieusement, passez 10 minutes à cliquer sur les propriétés. Vous verrouillerez le modèle mental plus rapidement que des heures de lecture de documentation.
Support navigateur
Une chose dont vous n'avez pas à vous inquiéter avec flexbox : le support navigateur. Flexbox est universellement supporté depuis environ 2015. Chaque navigateur moderne le supporte entièrement. Même IE 11 avait un support partiel (bien que si vous supportez encore IE 11, vous avez de plus grands problèmes).
Vous pouvez utiliser flexbox en toute confiance sans préfixes vendor ni polyfills. Les anciens préfixes -webkit-flex et -ms-flexbox sont depuis longtemps à la retraite. Écrivez simplement du flexbox standard et livrez.
Conclusion
Flexbox a cliqué pour moi au moment où j'ai arrêté de le considérer comme "une façon de déplacer des choses à gauche ou à droite" et commencé à le considérer comme un système d'axes et de comportements d'éléments. L'axe principal est là où vos éléments s'écoulent. L'axe transversal est perpendiculaire. justify-content contrôle l'axe principal. align-items contrôle l'axe transversal. Tout le reste découle de là.
Les modèles que j'utilise quotidiennement :
display: flex; justify-content: center; align-items: centerpour centrerjustify-content: space-betweenpour les navbars et toolbarsflex-wrap: wrapavecgappour les grilles responsivesflex: 1pour des éléments de largeur égale ou des zones de contenu croissantesflex-direction: column; min-height: 100vhavecflex: 1sur main pour les footers collants
Faites attention au problème de rétrécissement des images, au problème de débordement min-width: 0, et au fait que align-content a besoin d'éléments enroulés pour faire quoi que ce soit.
Flexbox est vraiment une de ces fonctionnalités CSS où une fois que vous avez le modèle mental, vous avez l'impression d'avoir débloqué un super pouvoir. Il ne remplace pas CSS Grid — utilisez les deux — mais pour les mises en page sur un seul axe, il est difficile de faire mieux.