Développement Web

Flexbox et Grid en utilities avec Tailwind CSS

14 دقائق للقراءة

Centrer un élément, répartir des cartes en colonnes égales, faire qu’une zone occupe l’espace restant : ces tâches de mise en page reviennent dans chaque interface, et elles ont longtemps été la partie la plus pénible du CSS. Flexbox et Grid les ont résolues au niveau du langage ; Tailwind les rend accessibles sans quitter votre HTML. La difficulté n’est plus la syntaxe, c’est de savoir quand employer l’un ou l’autre. À la fin de ce tutoriel, vous saurez choisir le bon outil et composer le tableau de bord complet de StockLab : une grille de fiches produit qui se réorganise proprement à chaque taille d’écran.

🎯 Ce que vous allez apprendre

  • Distinguer les cas où Flexbox est le bon choix de ceux où CSS Grid s’impose.
  • Construire une grille responsive de cartes avec grid, grid-cols-* et gap-*.
  • Contrôler l’alignement et la répartition avec items-*, justify-* et place-*.
  • Faire occuper plusieurs colonnes à un élément avec col-span-* et gérer les zones complexes.

🛠️ Ce que vous allez construire

Nous assemblons l’écran principal de StockLab : une rangée d’indicateurs en haut (nombre d’articles, valeur du stock, alertes), puis une grille de fiches produit en dessous. Sur mobile, une carte par ligne ; sur tablette, deux ; sur grand écran, quatre. Une carte « mise en avant » occupera deux colonnes. Tout est piloté par des utilitaires de mise en page.

Prérequis

  • Un projet Tailwind v4 opérationnel et la fiche produit construite précédemment.
  • Une compréhension de base des classes responsive (md:, lg:).
  • Test express : si vous savez ce que fait flex flex-col, vous êtes prêt à attaquer la grille.
  • ⏱️ Temps estimé : environ 35 minutes.

Flexbox ou Grid : le bon modèle mental

La règle qui évite 90 % des hésitations tient en une phrase : Flexbox pense en une dimension, Grid pense en deux. Flexbox dispose des éléments le long d’un seul axe — une ligne ou une colonne — et excelle quand on ne maîtrise pas le nombre exact d’éléments : une barre de navigation, une rangée de boutons, un en-tête. Grid, lui, organise un plan en lignes et colonnes simultanément : c’est l’outil des galeries, des tableaux de bord, des mises en page de page entière. Quand vous alignez des choses sur une seule rangée, pensez flex ; quand vous remplissez une surface en quadrillage, pensez grid. Les deux coexistent sans problème, et une interface réelle imbrique souvent l’un dans l’autre.

Étape 1 — La rangée d’indicateurs avec Grid

Les trois indicateurs du haut forment un quadrillage régulier : c’est un cas d’école pour Grid. On déclare une grille et on fixe le nombre de colonnes selon l’écran. Sur mobile, les indicateurs s’empilent ; à partir de la tablette, ils s’alignent sur trois colonnes.

<section class="grid grid-cols-1 gap-4 sm:grid-cols-3">
  <div class="rounded-lg bg-white p-6 shadow">
    <p class="text-sm text-gray-500">Articles</p>
    <p class="text-3xl font-bold text-gray-900">248</p>
  </div>
  <div class="rounded-lg bg-white p-6 shadow">
    <p class="text-sm text-gray-500">Valeur du stock</p>
    <p class="text-3xl font-bold text-gray-900">12,4 M</p>
  </div>
  <div class="rounded-lg bg-white p-6 shadow">
    <p class="text-sm text-gray-500">Alertes</p>
    <p class="text-3xl font-bold text-amber-600">5</p>
  </div>
</section>

grid active la grille, grid-cols-1 impose une colonne sur mobile, et sm:grid-cols-3 passe à trois colonnes dès 640 pixels. Le gap-4 gère tout l’espacement entre cellules — pas besoin de marges sur les enfants, ce qui élimine les fameux problèmes de marges qui s’additionnent ou se chevauchent. Le résultat : trois cartes parfaitement égales qui s’empilent proprement sur petit écran.

Point d’étape — Vos trois indicateurs s’alignent sur une rangée à partir de la tablette et s’empilent sur mobile, avec un espacement régulier. Si les colonnes ne sont pas égales, vérifiez que grid-cols-3 est bien sur le conteneur et non écrasé par un style de largeur sur les enfants.

Étape 2 — La grille de produits qui s’adapte

Passons à la galerie de fiches. Le besoin est clair : une carte par ligne sur téléphone, deux sur tablette, quatre sur grand écran. La même technique s’applique, en empilant les préfixes de point de rupture sur grid-cols-*.

<section class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
  <article class="rounded-lg bg-white p-4 shadow">Fiche 1</article>
  <article class="rounded-lg bg-white p-4 shadow">Fiche 2</article>
  <article class="rounded-lg bg-white p-4 shadow">Fiche 3</article>
  <article class="rounded-lg bg-white p-4 shadow">Fiche 4</article>
</section>

La progression grid-cols-1sm:grid-cols-2lg:grid-cols-4 décrit toute la responsivité de la galerie en trois mots-clés. Ajoutez ou retirez des fiches : la grille les replace automatiquement, sans que vous touchiez quoi que ce soit. C’est l’élégance de Grid : vous décrivez la structure, le navigateur gère le placement.

Étape 3 — Une carte en avant sur deux colonnes

Mettons un produit phare en valeur en lui faisant occuper deux colonnes au lieu d’une, à partir des grands écrans. C’est le rôle de col-span-*, qui indique combien de colonnes de la grille un enfant doit couvrir.

<section class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
  <article class="rounded-lg bg-indigo-600 p-4 text-white shadow sm:col-span-2">
    Produit en avant
  </article>
  <article class="rounded-lg bg-white p-4 shadow">Fiche 2</article>
  <article class="rounded-lg bg-white p-4 shadow">Fiche 3</article>
</section>

sm:col-span-2 demande à la première carte de couvrir deux colonnes dès que la grille en propose au moins deux. Les autres fiches s’écoulent autour. Vous disposez ainsi de col-span-1 à col-span-12, plus col-span-full pour traverser toute la largeur — pratique pour un bandeau ou un titre de section. La même mécanique existe sur les lignes avec row-span-* pour les cartes qui doivent être plus hautes.

Point d’étape — La carte en avant occupe bien deux cellules de large à partir de la tablette, et les autres se réorganisent autour sans trou. Si elle déborde, c’est que le nombre de colonnes demandé par col-span dépasse celui de la grille à ce point de rupture.

Étape 4 — Aligner et répartir le contenu

Au sein d’une carte, on a souvent besoin de centrer une icône, ou de coller un prix en bas. Flexbox est ici l’outil idéal car on travaille sur un seul axe. Reprenons une fiche et alignons son contenu verticalement, en poussant le prix tout en bas.

<article class="flex h-48 flex-col justify-between rounded-lg bg-white p-4 shadow">
  <h3 class="font-semibold text-gray-900">Visseuse sans fil</h3>
  <p class="text-2xl font-bold text-indigo-600">45 000</p>
</article>

La carte devient un conteneur flex en colonne avec une hauteur fixe ; justify-between répartit l’espace pour pousser le titre en haut et le prix en bas. Sur l’axe principal d’un flex, justify-* contrôle la répartition (start, center, between, around, evenly) et items-* l’alignement transversal. Quand vous voulez les deux réglages d’un coup dans une grille, Tailwind propose les raccourcis place-items-center et place-content-center qui combinent l’alignement horizontal et vertical en une seule classe — la manière la plus concise de centrer parfaitement un contenu.

Étape 5 — Quand Flexbox gère un nombre inconnu d’éléments

Imaginons une rangée d’étiquettes de catégories sous chaque produit, en nombre variable. Grid imposerait un quadrillage rigide ; Flexbox avec retour à la ligne est bien plus adapté car il laisse les éléments s’écouler et passer à la ligne naturellement.

<div class="flex flex-wrap gap-2">
  <span class="rounded-full bg-gray-100 px-3 py-1 text-xs">Outillage</span>
  <span class="rounded-full bg-gray-100 px-3 py-1 text-xs">Électroportatif</span>
  <span class="rounded-full bg-gray-100 px-3 py-1 text-xs">Promo</span>
</div>

flex flex-wrap laisse les étiquettes sur une ligne tant qu’il y a la place, puis les fait passer à la ligne suivante quand l’espace manque, avec gap-2 qui maintient l’espacement dans les deux directions. C’est exactement le genre de cas où Grid serait contre-productif : vous ne connaissez pas le nombre d’étiquettes, et vous voulez qu’elles se serrent naturellement. Voilà la frontière concrète entre les deux outils.

Les unités qui changent tout : fr, minmax et auto-fit

Pour les grilles vraiment fluides, Grid offre des mécaniques que les colonnes fixes ne permettent pas. Avec une valeur arbitraire, vous accédez à grid-template-columns dans toute sa puissance, notamment la combinaison repeat(auto-fit, minmax(…)) qui crée autant de colonnes que la largeur le permet, sans aucun point de rupture.

<section class="grid grid-cols-[repeat(auto-fit,minmax(220px,1fr))] gap-4">
  <article class="rounded-lg bg-white p-4 shadow">Fiche</article>
</section>

Cette déclaration dit : « crée des colonnes d’au moins 220 pixels, et autant que possible, chacune prenant une part égale de l’espace restant ». La grille se réarrange seule à toutes les largeurs, sans sm: ni lg:. L’unité fr représente une fraction de l’espace disponible ; minmax fixe une borne basse pour que les cartes ne deviennent jamais illisibles. C’est l’arme idéale quand le nombre de colonnes doit dépendre purement de la place, pas d’un seuil arbitraire.

Comprendre l’échelle d’espacement, la colonne vertébrale de la cohérence

Un détail passe souvent inaperçu mais explique pourquoi les interfaces Tailwind paraissent soignées : l’espacement repose sur une échelle numérique cohérente, pas sur des valeurs choisies au hasard. Quand vous écrivez gap-4, p-6 ou mt-2, le chiffre n’est pas un nombre de pixels arbitraire : c’est un cran sur une échelle où chaque unité vaut 0,25 rem, soit 4 pixels à la taille par défaut. Ainsi gap-4 produit 16 pixels, p-6 24 pixels, gap-2 8 pixels. Cette régularité a une vertu cachée : comme tous les espacements de votre interface sont des multiples du même pas, ils s’harmonisent naturellement, sans que vous ayez à y penser. C’est l’opposé du CSS écrit à la main, où l’on finit toujours avec un 13px ici et un 19px là qui donnent ce vague sentiment de désordre.

Cette discipline s’étend aux tailles. w-40, h-48, max-w-md puisent dans la même logique d’échelle. Le bénéfice concret pour StockLab : quand vous ajoutez un nouvel écran des mois plus tard, vous réutilisez les mêmes crans et le résultat reste visuellement cohérent avec l’existant, même sans maquette détaillée sous les yeux. La contrainte devient une aide. Et si un design impose vraiment une valeur hors échelle, la notation entre crochets — gap-[18px] — reste disponible pour l’exception, sans jamais devenir la règle.

Imbriquer Flexbox et Grid dans une interface réelle

Dans la théorie, on oppose Flexbox et Grid ; dans la pratique, on les emboîte. Une fiche produit complète de StockLab illustre parfaitement cette collaboration : la galerie est une grille, mais l’intérieur de chaque carte est un flex. La grille place les cartes ; le flex organise le contenu de chacune.

<section class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
  <article class="flex flex-col justify-between rounded-lg bg-white p-4 shadow">
    <div class="flex items-center justify-between">
      <h3 class="font-semibold">Visseuse</h3>
      <span class="rounded-full bg-green-100 px-2 py-1 text-xs text-green-700">En stock</span>
    </div>
    <p class="mt-4 text-2xl font-bold text-indigo-600">45 000</p>
  </article>
</section>

Observez les trois niveaux. Le <section> est une grille qui répartit les cartes. Chaque <article> est un flex vertical qui pousse le prix vers le bas. À l’intérieur, le bandeau titre + badge est lui-même un flex horizontal avec justify-between. Personne ne se marche dessus : chaque conteneur gère son propre axe. C’est cette composition en couches qui permet de bâtir des interfaces riches sans jamais écrire de CSS — on assemble des conteneurs, chacun avec sa logique d’alignement.

Pour les cas les plus exigeants, où l’on veut qu’un contenu enfant s’aligne sur la grille de son parent, Tailwind expose grid-cols-subgrid et grid-rows-subgrid. Le subgrid permet à une carte d’hériter des pistes de la grille parente, de sorte que titres et prix de plusieurs cartes voisines s’alignent au pixel près, même si leurs contenus ont des hauteurs différentes. C’est un raffinement, pas un point de départ : gardez-le pour le jour où l’alignement vertical entre cartes deviendra une vraie exigence de design.

🐞 Pièges fréquents

Symptôme / erreur Cause probable Correctif
Les colonnes de la grille ne sont pas égales Une largeur fixe sur un enfant écrase la répartition de Grid Retirer les w-* des enfants ; laisser grid-cols-* gérer
justify-between ne fait rien Appliqué sur un conteneur qui n’est pas flex ou grid Ajouter flex (ou grid) sur le conteneur parent
Les marges entre cartes sont irrégulières Marges manuelles sur les enfants au lieu de gap Supprimer les marges, utiliser gap-4 sur le conteneur
Une carte col-span-2 déborde sur mobile La grille n’a qu’une colonne à ce point de rupture Préfixer : sm:col-span-2 pour ne l’activer qu’au-delà

✅ Récapitulatif

Vous savez maintenant trancher entre Flexbox et Grid : une dimension contre deux, nombre variable contre quadrillage régulier. Vous avez bâti la rangée d’indicateurs et la galerie de produits de StockLab, fait occuper deux colonnes à une carte phare, aligné le contenu avec justify-between et place-items-center, géré des étiquettes en nombre libre avec flex-wrap, et découvert les grilles auto-adaptatives avec auto-fit et minmax. Le tableau de bord prend forme, et chaque choix de mise en page est désormais un choix conscient.

🧾 Aide-mémoire

Classe Effet
grid grid-cols-4 gap-4 Grille de 4 colonnes avec espacement
col-span-2 / col-span-full Couvrir 2 colonnes / toute la largeur
flex flex-wrap gap-2 Ligne flexible avec retour à la ligne
justify-between / items-center Répartir / aligner sur l’axe flex
place-items-center Centrer horizontalement et verticalement en grid
grid-cols-[repeat(auto-fit,minmax(220px,1fr))] Colonnes auto-adaptatives sans point de rupture

💪 À vous de jouer

Transformez la galerie pour qu’elle affiche trois colonnes sur grand écran au lieu de quatre, et faites en sorte que la première carte occupe toute la largeur en guise de bannière, sur tous les écrans.

Voir une solution
<section class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
  <article class="col-span-full rounded-lg bg-indigo-600 p-6 text-white">Bannière</article>
  <article class="rounded-lg bg-white p-4 shadow">Fiche</article>
</section>

lg:grid-cols-3 ramène la galerie à trois colonnes sur grand écran ; col-span-full sans préfixe fait traverser la bannière sur toute la largeur, quelle que soit la taille d’écran.

Tutoriels frères

Ressources et références

FAQ

Q : Dois-je toujours préférer Grid à Flexbox puisqu’il est plus puissant ?
R : Non. Pour une mise en page sur un seul axe avec un nombre d’éléments inconnu — une barre de navigation, une rangée d’étiquettes — Flexbox est plus simple et plus naturel. Réservez Grid aux structures à deux dimensions.

Q : Pourquoi utiliser gap plutôt que des marges ?
R : gap espace les éléments sans créer de marge en bordure du conteneur, et il fonctionne identiquement en flex et en grid. Il évite les marges qui s’additionnent ou fuient hors du conteneur.

Q : Comment centrer parfaitement un élément, horizontalement et verticalement ?
R : La voie la plus courte est grid place-items-center sur le conteneur. En flex, combinez flex items-center justify-center.

Q : auto-fit ou points de rupture : que choisir ?
R : Si le nombre de colonnes doit dépendre uniquement de la largeur disponible, auto-fit avec minmax est plus fluide. Si vous voulez un contrôle précis à chaque seuil, les préfixes sm:/lg: restent plus explicites.

مشاركة