En CSS, on a deux propriétés fondamentales qui servent à organiser des éléments : Flexbox et Grid. La question qui revient tout le temps, c'est : comment savoir laquelle utiliser selon le cas ? Je vais vous expliquer comment je m'y prends pour décider, et surtout comment j'ai fini par vraiment comprendre ces deux notions.
Elles ne font pas la même chose
La première chose à comprendre, c'est que Flexbox et Grid n'ont pas la même fonction. Flexbox sert à organiser des éléments soit horizontalement, soit verticalement - jamais les deux en même temps. Grid, lui, sert à organiser des éléments en colonnes et en lignes en même temps, donc horizontalement ET verticalement à la fois. C'est cette seule différence qui change tout dans le choix qu'on va faire.
Cas n°1 : une rangée d'icônes (le terrain de Flexbox)
Prenons un petit cadre devant nous, et organisons-y horizontalement une liste de six icônes.
<div class="icon-row">
<span class="icon">1</span>
<span class="icon">2</span>
<span class="icon">3</span>
<span class="icon">4</span>
<span class="icon">5</span>
<span class="icon">6</span>
</div>
.icon-row {
display: flex;
gap: 12px;
align-items: center;
}
Rendu
Trois lignes de CSS, et les six icônes se retrouvent parfaitement alignées côte à côte, espacées régulièrement, centrées verticalement entre elles. C'est exactement le genre de cas où Flexbox excelle : une seule rangée, une seule direction à gérer.
Et si on fait pareil avec Grid ?
Essayons maintenant de faire la même chose avec Grid, pour bien voir la différence :
.icon-row {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 12px;
}
Rendu
Visuellement, presque identique au rendu Flexbox ci-dessus - c'est justement ce qui rend la différence facile à manquer.
Le résultat visuel est presque identique - les six icônes sont alignées en rangée. Mais regardez la différence : avec Grid, j'ai dû dire explicitement qu'il y avait 6 colonnes (repeat(6, 1fr)). Avec Flexbox, je n'ai eu à préciser aucun nombre de colonnes - les éléments se rangent naturellement les uns à côté des autres, autant qu'il y en a.
C'est là le premier signal qui doit orienter votre choix : si vous ne voulez pas avoir à penser en termes de « colonnes » ou de « lignes » précises, et que vous voulez juste que les éléments s'alignent naturellement dans un sens, Flexbox est plus simple et plus adapté.
Et si l'espace manque, ça passe à la ligne ?
Bonne question à se poser, et la réponse est un peu contre-intuitive : par défaut, non. Flexbox a flex-wrap: nowrap par défaut, ce qui veut dire que tous les éléments restent sur une seule ligne, quoi qu'il arrive. Si l'espace manque, les éléments vont plutôt rétrécir pour essayer de tenir tous ensemble - et s'ils ne peuvent plus rétrécir davantage, ils débordent du conteneur plutôt que de passer à la ligne.
Pour qu'ils passent réellement à la ligne quand l'espace manque, il faut le demander explicitement :
.icon-row {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
Rendu - cadre volontairement étroit, pour provoquer le retour à la ligne
Avec flex-wrap: wrap, dès que l'espace manque, les éléments en trop redescendent sur une nouvelle ligne - un peu comme des mots dans un paragraphe qui passent à la ligne suivante. C'est une source assez classique de bugs pour les débutants : on code une rangée de boutons ou de cartes, ça marche bien sur grand écran, et puis sur mobile tout se retrouve écrasé et illisible parce qu'on a oublié flex-wrap: wrap. Le réflexe à prendre : dès qu'un conteneur flex peut recevoir un contenu de largeur variable ou s'afficher sur un petit écran, pensez à flex-wrap: wrap par sécurité - sauf si vous voulez vraiment que ça tienne coûte que coûte sur une seule ligne, auquel cas nowrap (le défaut) est le bon choix.
La suite (le cas Grid en pratique, et comment je décide concrètement entre les deux) est réservée aux contributeurs.