Répartir parfaitement des items avec width: calc(…) et Flexbox

Comment répartir des cartes avec Flexbox sans que la dernière ligne ne s'étire ? La formule width: calc() expliquée pas à pas, avec le responsive et son application dans Elementor.

width: calc(...) avec Flebox
Sommaire

Quand on crée une grille de cartes avec Flexbox, on veut souvent trois éléments par ligne, avec des espaces constants entre eux. Tout va bien… jusqu'à la dernière ligne. Comment gérer une ligne qui ne contient qu'un ou deux éléments ?

La réponse tient en une ligne de CSS : width: calc(). Voici comment elle fonctionne, comment la rendre responsive, et comment l'appliquer dans Elementor.

Sept cartes réparties trois par ligne. Avec flex: 1, la septième carte s’étire sur toute la dernière ligne. Avec width: calc((100% - 40px) / 3), elle garde la même largeur que les autres, alignée à gauche. En ajoutant justify-content: center, la dernière ligne est centrée..container1234567

L'essentiel en bref

  • La formule : width: calc((100% - espaces) / colonnes)
  • Les espaces = (nombre de colonnes - 1) × gap
  • Le résultat : toutes les cartes gardent la même largeur, même sur une ligne incomplète
  • Le bonus : justify-content: center pour centrer la dernière ligne

Le problème classique

Prenons un conteneur avec trois cartes par ligne. Avec 3, 6 ou 9 cartes, tout va bien. Mais avec 4, 5 ou 7 cartes, la dernière ligne est incomplète, et les éléments peuvent :

  • S'étirer sur toute la largeur avec flex: 1, qui partage l'espace restant entre les éléments de la ligne ;
  • Déborder à la ligne avec width: 33.33%, qui oublie de compter les espaces entre les cartes ;
  • Se désaligner par rapport aux lignes du dessus.

La solution : width: calc()

Plutôt que de laisser le navigateur répartir l'espace, on calcule nous-mêmes la largeur exacte de chaque élément avec calc() :

width: calc((100% - 80px) / 3);

La formule width: calc((100% - 80px) / 3) expliquée sur un conteneur de 1200 pixels : on retire les deux espaces de 40 pixels, il reste 1120 pixels, divisés en trois éléments de 373,33 pixels. Formule générale : calc((100% - (colonnes - 1) × gap) / colonnes).width: calc((100% - 80px) / 3);Conteneur1200 px40 px40 px373,33 px373,33 px373,33 pxFORMULE GÉNÉRALEcalc((100% - (colonnes - 1) × gap) / colonnes)
  • 100% : la largeur totale du conteneur ;
  • 80px : la somme des espaces entre les trois éléments, soit deux gap de 40 px ;
  • / 3 : le nombre d'éléments souhaités par ligne.

Même si une ligne ne contient qu'un ou deux éléments, leur largeur reste identique à celle des autres, et ils ne s'étirent plus. Attention : il y a toujours un espace de moins que de colonnes. Pour 4 colonnes avec un gap de 40 px, on retire donc 120 px.

Exemple concret

Une grille de cinq éléments : trois sur la première ligne, deux sur la seconde.

HTML

<div class="container"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> </div>

CSS

.container { display: flex; flex-wrap: wrap; gap: 40px; } .item { width: calc((100% - 80px) / 3); box-sizing: border-box; padding: 20px; background: #eee; }

  • flex-wrap: wrap autorise les éléments à passer à la ligne quand il n'y a plus de place.
  • gap crée les espaces entre les éléments, sans marge à gérer sur le premier ou le dernier.
  • box-sizing: border-box inclut le padding dans la largeur calculée. Sans lui, chaque carte serait 40 px trop large et la troisième passerait à la ligne.

Centrer la dernière ligne

Par défaut, les éléments de la dernière ligne se placent à gauche. Comme leur largeur est fixe, une seule propriété suffit pour les centrer :

.container { justify-content: center; /* flex-start par défaut */ }

C'est là que Flexbox fait mieux que CSS Grid : avec une grille, la dernière ligne reste toujours collée à gauche.

Ajouter le responsive

Sur tablette et sur mobile, trois colonnes deviennent trop étroites. On adapte donc le nombre de colonnes avec des media queries, en recalculant la largeur à chaque fois.

Le conteneur passe de 1200 à 900 puis à 375 pixels de large. Les éléments passent de trois colonnes sur ordinateur à deux sur tablette, puis une seule sur mobile, grâce à une media query par format.1234563 colonnes · 373 px par élément

La version classique

@media (min-width: 1024px) { .item { width: calc((100% - 80px) / 3); } } @media (min-width: 768px) and (max-width: 1023px) { .item { width: calc((100% - 40px) / 2); } } @media (max-width: 767px) { .item { width: 100%; } }

La version avec variables CSS

Plus élégant : on stocke l'écart et le nombre de colonnes dans des variables. La formule ne s'écrit qu'une fois, et chaque media query ne change plus qu'un chiffre.

.container { --gap: 40px; --cols: 3; display: flex; flex-wrap: wrap; gap: var(--gap); } .item { width: calc((100% - (var(--cols) - 1) * var(--gap)) / var(--cols)); } @media (max-width: 1023px) { .container { --cols: 2; } } @media (max-width: 767px) { .container { --cols: 1; } }

Ces points de rupture sont proches de ceux d'Elementor pour la tablette et le mobile. Pour aller plus loin, lisez notre article sur les media queries CSS avec Elementor.

Et dans Elementor ?

Pas besoin d'écrire de CSS : tous les réglages existent dans l'éditeur.

Avec Elementor V4

  1. Ajoutez un conteneur Flexbox en direction ligne, avec le retour à la ligne activé (wrap) et un écart de 40 px.
  2. Créez une classe pour les cartes, par exemple .carte, et appliquez-la à chaque élément enfant.
  3. Dans la classe, réglez la largeur avec une valeur personnalisée : calc((100% - 80px) / 3).
  4. Passez en affichage tablette puis mobile, et remplacez la valeur par calc((100% - 40px) / 2), puis par 100 %.
  5. Pour centrer la dernière ligne, réglez la justification du conteneur sur « centre ».

En V3, le principe est identique : un conteneur Flexbox avec retour à la ligne, et une largeur personnalisée sur chaque élément. Pour découvrir les classes et les variables, lisez notre guide complet d'Elementor V4.

Flexbox + calc() ou CSS Grid ?

CSS Grid répond au même besoin avec moins de calculs :

.container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; }

Flexbox + calc()

Pour centrer

Idéal quand la dernière ligne doit être centrée, ou quand vous voulez garder la main sur la largeur exacte de chaque élément.

CSS Grid

Pour aligner

Plus simple pour une grille stricte, alignée à gauche. Avec repeat(auto-fit, minmax(250px, 1fr)), elle devient même responsive sans media query. Elle existe aussi en élément atomique depuis Elementor 4.2.

Questions fréquentes

Pourquoi retirer 80 px et pas 40 px ?

Parce qu'il y a deux espaces entre trois éléments. La règle : (nombre de colonnes - 1) × gap. Pour 4 colonnes et un gap de 40 px, on retire donc 120 px.

Pourquoi ne pas utiliser flex: 1 ?

flex: 1 partage l'espace disponible entre les éléments de chaque ligne. Sur une ligne incomplète, les éléments restants s'étirent pour remplir toute la largeur.

Et width: 33.33 % ?

Cette valeur ne tient pas compte des espaces. Trois éléments de 33,33 % plus deux gap dépassent 100 %, et le troisième passe à la ligne.

calc() fonctionne-t-il sur tous les navigateurs ?

Oui. calc() est reconnu par tous les navigateurs actuels depuis des années, tout comme la propriété gap avec Flexbox.

Que faire si l'écart change sur mobile ?

Il faut adapter la formule, car le montant retiré dépend du gap. C'est tout l'intérêt de la version avec variables CSS : changez --gap, la largeur se recalcule toute seule.

Un projet en tête ?

Parlons de votre prochain site web

Site vitrine, refonte, identité visuelle ou référencement : Alpixi accompagne les entreprises des Alpes et d'ailleurs, avec un interlocuteur unique du premier échange à la mise en ligne.

★★★★★

Noté 5/5 par nos clients sur Google


Contact direct

06 76 45 01 16

bonjour@alpixi.com

Agence basée à Autrans-Méaudre en Vercors