Aller au contenu
wasabi web designDevis gratuit
Web design

CSS Clamp() : Le secret pour un design parfaitement fluide (et sans media queries)

clamp() en CSS : syntaxe, calcul d’une taille de texte fluide, effet du zoom sur l’accessibilité et compatibilité, avec des exemples à copier.

  • Publié le
  • Mis à jour le
  • 14 min de lecture
La taille des éléments varie entre une borne minimale et une borne maximale.
Au programme 10 sections
  1. 1. Qu’est-ce que clamp() exactement ?
  2. 2. La logique mathématique
  3. 3. La typographie fluide, l’usage principal
  4. 4. Le piège de l’accessibilité, et comment l’éviter
  5. 5. Au-delà du texte : mise en page et espacements
  6. 6. Aller plus loin : les variables CSS
  7. 7. Les outils pour ne pas devenir fou
  8. 8. Quand ne pas utiliser clamp() ?
  9. 9. Compatibilité avec les navigateurs
  10. Conclusion : vers un web plus organique

L’essentiel

clamp(MIN, IDÉAL, MAX) garde une valeur CSS entre un minimum et un maximum : avec font-size: clamp(2rem, 1rem + 3vw, 4rem), un titre grandit avec la fenêtre, de 32 à 64 px, sans media query. La fonction marche dans Chrome, Edge, Firefox et Safari depuis 2020. Pour du texte, gardez une part en rem, un maximum au plus 2,5 fois plus grand que le minimum, et vérifiez au zoom que le texte peut doubler.

Si vous développez des sites web depuis plus de quelques années, vous connaissez ce sentiment de frustration. Vous venez de terminer l’intégration d’une maquette magnifique sur votre grand écran 27 pouces. Tout est parfait. Les titres sont majestueux, les marges aérées.

Puis, vous réduisez la fenêtre du navigateur pour simuler un ordinateur portable. Crac. Le titre passe sur trois lignes.
Vous réduisez encore pour simuler une tablette. Boum. Les marges écrasent le contenu.
Vous passez à la taille d’un téléphone. Catastrophe.

La solution classique ? Le réflexe de l’intégrateur : ajouter une media query. Puis une deuxième. Puis une troisième pour les grands écrans.

h1 { font-size: 22px; }
@media (min-width: 768px) { h1 { font-size: 32px; } }
@media (min-width: 1024px) { h1 { font-size: 48px; } }
@media (min-width: 1440px) { h1 { font-size: 64px; } }

Résultat ? Un code CSS verbeux, difficile à maintenir, et une expérience utilisateur en « escalier » (le design saute brutalement d’une étape à l’autre).

Le CSS a beaucoup évolué. En 2018, lors d’une conférence, Jen Simmons a donné un nom à cette nouvelle façon de faire : le « design intrinsèque » (Intrinsic Web Design). Les mises en page s’adaptent d’elles-mêmes à la place disponible, avec des media queries seulement quand il le faut. La fonction clamp(), arrivée peu après dans les navigateurs, va dans ce sens.

Dans cet article, nous allons décortiquer cette fonction, comprendre sa logique mathématique, explorer ses cas d’usage (bien au-delà de la taille de police), aborder l’accessibilité et voir comment l’intégrer à votre méthode de travail. clamp() ne supprime pas toutes les media queries : il remplace celles qui ne servent qu’à changer une taille ou un espacement.

1. Qu’est-ce que clamp() exactement ?

Pour comprendre clamp(), il faut arrêter de penser en « pixels fixes » et commencer à penser en « contraintes ».

clamp() est une fonction CSS mathématique qui permet d’encadrer une valeur qui change. Imaginez-la comme un garde-fou intelligent. Elle dit au navigateur :

« Je veux que cette propriété ait cette valeur idéale, mais attention : elle ne doit jamais descendre en dessous de ce minimum, ni dépasser ce maximum. »

La syntaxe décortiquée

La fonction accepte trois paramètres, séparés par des virgules :

propriété: clamp(MINIMUM, IDÉAL, MAXIMUM);
  1. MINIMUM (le plancher) : c’est la limite basse. Quoi qu’il arrive, même si votre fenêtre de navigateur devient minuscule, la valeur calculée ne descendra jamais en dessous de ce seuil.
  2. IDÉAL (la valeur préférée) : c’est elle qui varie. Elle dépend en général de la largeur de la fenêtre (unité vw) ou de celle d’un conteneur (unité cqi). Un pourcentage (%), lui, dépend de l’élément parent. Le navigateur utilise cette valeur tant qu’elle reste entre le minimum et le maximum.
  3. MAXIMUM (le plafond) : c’est la limite haute. Sur un écran de cinéma, votre élément n’ira pas plus loin que cette valeur.

L’analogie du thermostat

Imaginez une climatisation réversible, qui chauffe ou rafraîchit la pièce.

  • Vous réglez la température idéale sur « la température extérieure » (c’est la valeur qui change).
  • Mais vous dites : « Ne descends jamais en dessous de 18 °C » (il ferait trop froid).
  • Et vous dites : « Ne monte jamais au-dessus de 25 °C » (il ferait trop chaud).

S’il fait 10 °C dehors, elle chauffe la pièce à 18 °C.
S’il fait 22 °C, elle la garde à 22 °C.
S’il fait 35 °C, elle la rafraîchit à 25 °C.

C’est exactement ce que fait clamp() avec vos pixels.

2. La logique mathématique

Il est intéressant de savoir comment le navigateur interprète cette fonction. Pour les puristes du code, clamp() est en réalité du sucre syntaxique (une manière plus simple d’écrire quelque chose de complexe).

Écrire :

width: clamp(300px, 50%, 800px);

Revient exactement à écrire cette combinaison de fonctions min() et max() :

width: max(300px, min(50%, 800px));

Le navigateur effectue le calcul en deux temps :

  1. Il compare la valeur idéale (50%) et le maximum (800px) et prend la plus petite des deux (min()).
  2. Il compare le résultat obtenu avec le minimum (300px) et prend la plus grande des deux (max()).

Heureusement, clamp() est beaucoup plus lisible humainement. Cette compréhension est toutefois utile pour le débogage : si votre clamp ne fonctionne pas comme prévu, c’est souvent parce que vos unités sont incompatibles ou que votre logique min/max est inversée. Si le minimum dépasse le maximum, c’est le minimum qui l’emporte, comme le prévoit la spécification CSS : clamp(100px, 50vw, 50px) vaut toujours 100 px. Et si les types ne vont pas ensemble (une longueur et un nombre sans unité, par exemple), toute la déclaration est ignorée.

Création · Site vitrine

Un site vitrine qui fait venir des demandes, même quand vous êtes sur le terrain.

Design sur mesure, référencement local intégré dès la première ligne de code, hébergement et mises à jour compris.

Délai
1 à 4 semaines
À partir de
89 € HT / mois
Ou
paiement unique sur devis

Demander un devisVoir l’offre

3. La typographie fluide, l’usage principal

C’est l’utilisation qui a popularisé clamp(). La typographie fluide consiste à avoir une taille de texte qui grandit linéairement avec la fenêtre, plutôt que par à-coups, à chaque point de rupture (breakpoint).

Le problème du vw seul

Avant clamp(), certains développeurs utilisaient seulement l’unité de fenêtre vw :

h1 { font-size: 5vw; } /* 5 % de la largeur de la fenêtre */

C’est une très mauvaise idée.

  • Sur un téléphone de 375 px de large : 5vw = 18,75 px. C’est à peine plus qu’un texte courant, pour un titre principal.
  • Sur une fenêtre de 1 920 px de large : 5vw = 96 px. C’est énorme.

La solution : clamp()

Nous allons définir des bornes de sécurité.

h1 {
  font-size: clamp(2rem, 5vw, 4rem);
}

(Supposons que 1rem = 16px)

  • Minimum : 32 px (2rem). Le titre reste lisible sur un téléphone.
  • Idéal : 5vw. Le titre grossit avec la fenêtre, de 640 à 1 280 px de large.
  • Maximum : 64 px (4rem). Le titre ne deviendra pas grotesque sur un iMac.

Une seule déclaration remplace les trois media queries du début, et la taille change sans à-coups. Attention : les valeurs ne sont pas les mêmes (32 px au lieu de 22 px sur téléphone, 64 px dès 1 280 px de large au lieu de 1 440 px) ; choisissez vos bornes d’après votre maquette.

4. Le piège de l’accessibilité, et comment l’éviter

Avant de copier le code ci-dessus (clamp(2rem, 5vw, 4rem)), vérifiez ce qu’il devient quand on zoome.

Quand un utilisateur malvoyant zoome dans son navigateur (Ctrl + sur Windows, Cmd + sur Mac), les pixels CSS grossissent : les tailles en px, em ou rem grossissent à l’écran. Une taille en vw, elle, ne bouge pas : la fenêtre compte moins de pixels CSS, et 1vw en vaut moins.

Un titre en 5vw seul ne grossit donc jamais. Les règles d’accessibilité du W3C (WCAG) en font un cas d’échec (F94) du critère 1.4.4, qui demande un texte agrandissable jusqu’à 200 %. Avec clamp(2rem, 5vw, 4rem), le titre ne grossit qu’une fois le minimum atteint. Dans une fenêtre de 1 280 px de large, il garde ses 64 px à 200 % de zoom, et ne double qu’à 400 %.

Mêler rem et vw

Pour améliorer les choses, mêlez à l’unité de fenêtre (vw) une unité qui suit le zoom (rem), dans la valeur centrale.

Au lieu de 5vw, nous allons utiliser un calcul :

/* Avant : la valeur centrale ne suit pas le zoom */
h1 { font-size: clamp(2rem, 5vw, 4rem); }

/* Après : une part en rem suit le zoom et la taille de texte choisie */
h1 { font-size: clamp(2rem, 1rem + 3vw, 4rem); }

Ce que ça change
La part en rem grossit avec le zoom, et suit la taille de texte choisie dans les réglages du navigateur. La part en vw, non. Le texte grossit donc dès le premier cran de zoom, mais moins vite que le zoom : dans une fenêtre de 1 280 px, ce titre passe de 54 à 70 px à 200 % de zoom, et ne double qu’au-delà de 300 %. Ce n’est donc pas une garantie.

Ce qui compte surtout, c’est l’écart entre le minimum et le maximum. MDN conseille un maximum en rem au moins deux fois plus grand que le minimum. Maxwell Barvian (Smashing Magazine, 2023) a montré qu’avec un maximum au plus 2,5 fois plus grand que le minimum, le texte peut toujours doubler en zoomant jusqu’à 500 %, le zoom maximal de Chrome et de Firefox sur ordinateur. Ici, 4rem vaut deux fois 2rem : les deux repères sont respectés. Dans tous les cas, testez : zoomez à 200 %, puis au-delà, et regardez si le texte double. Adrian Roselli, spécialiste de l’accessibilité, le rappelait encore en octobre 2025 : aucune recette toute faite n’est garantie.

C’est un détail technique, mais il compte pour les personnes qui agrandissent le texte. Les mêmes lecteurs profitent d’un contraste suffisant entre le texte et le fond et d’un texte aligné à gauche plutôt que centré ou justifié.

5. Au-delà du texte : mise en page et espacements

La typographie n’est qu’un début : clamp() sert aussi à la mise en page. Le design intrinsèque veut des composants qui s’adaptent d’eux-mêmes à la place disponible, et des media queries seulement quand il le faut.

A. Des conteneurs intelligents

Souvent, on veut qu’une section occupe une certaine largeur, mais pas trop.
Traditionnellement :

.container {
  width: 90%;
  max-width: 1200px;
  min-width: 320px;
}

Avec clamp, c’est une seule ligne :

.container {
  width: clamp(320px, 90%, 1200px);
}

Le résultat est le même : seule l’écriture est plus courte. Attention au minimum : 320 px débordent d’une fenêtre plus étroite, au fort zoom par exemple (une fenêtre de 1 280 px zoomée à 500 % ne compte plus que 256 px CSS). Souvent, width: min(90%, 1200px) suffit, sans risque de débordement sur un très petit écran.

B. Des espacements fluides

C’est mon astuce préférée. Des espacements énormes (80 px) sur téléphone mangent la place utile. Des espacements serrés (20 px) sur ordinateur donnent un aspect tassé.

Au lieu d’écrire des media queries pour changer le padding d’une section ou l’écart (gap) entre les cellules d’une grille :

.section {
  /* Espacement vertical : de 2rem à 5rem */
  padding-block: clamp(2rem, 5vw, 5rem);

  /* Espacement horizontal : de 1rem à 10rem */
  padding-inline: clamp(1rem, 5vw, 10rem);
}

.grille {
  /* Écart entre les cellules : de 1rem à 2.5rem */
  gap: clamp(1rem, 3vw, 2.5rem);
}

Cela crée une « respiration » dynamique. L’espacement vertical passe de 32 px (jusqu’à 640 px de large) à 80 px (dès 1 600 px). Sur téléphone, votre contenu reste compact. Sur grand écran, la page s’aère d’elle-même, sans que vous ayez écrit une seule ligne de @media.

C. Des hauteurs fluides

Imaginez une image d’en-tête. Sur téléphone, vous la voulez assez haute pour voir le détail. Sur ordinateur, moins haute par rapport à sa largeur, pour ne pas pousser le contenu trop bas. Donnez-lui une hauteur fluide :

.bandeau img {
  width: 100%;
  height: clamp(16rem, 40vw, 30rem);
  object-fit: cover;
}

L’image fait ainsi 256 px de haut sur un téléphone de 375 px, 307 px à 768 px de large et 480 px dès 1 200 px. clamp() marche aussi sur d’autres propriétés, comme border-radius.

6. Aller plus loin : les variables CSS

Le vrai pouvoir de clamp() se révèle lorsqu’on le combine avec les variables CSS (les « propriétés personnalisées »). On obtient un système de design entièrement fluide.

Imaginez définir votre échelle de taille à la racine du projet :

:root {
  /* Définition des fluides */
  --fluid-sm: clamp(0.8rem, 0.17vw + 0.76rem, 0.89rem);
  --fluid-base: clamp(1rem, 0.34vw + 0.91rem, 1.19rem);
  --fluid-md: clamp(1.25rem, 0.61vw + 1.1rem, 1.58rem);
  --fluid-lg: clamp(1.56rem, 1vw + 1.31rem, 2.11rem);
  --fluid-xl: clamp(1.95rem, 1.56vw + 1.56rem, 2.81rem);
  --fluid-xxl: clamp(2.44rem, 2.38vw + 1.85rem, 3.75rem);
}

body {
  font-size: var(--fluid-base);
}

h1 {
  font-size: var(--fluid-xxl);
}

h2 {
  font-size: var(--fluid-xl);
}

Avec cette configuration, toute votre typographie est fluide par défaut. Vous réglez les tailles une fois, dans :root, et tout le site suit.

7. Les outils pour ne pas devenir fou

Vous avez remarqué les valeurs de la section précédente (0.34vw + 0.91rem) ? Personne ne les calcule de tête. C’est pourtant une simple équation de droite (y = ax + b). Exemple : un texte de 16 px dans une fenêtre de 320 px de large, et de 19 px à 1 200 px. La pente vaut (19 − 16) ÷ (1 200 − 320) ≈ 0,003409, soit 0.3409vw (1vw vaut 1 % de la largeur). Le point de départ vaut 16 − 0,003409 × 320 ≈ 14,91 px, soit 0.9318rem (14,91 ÷ 16). On obtient clamp(1rem, 0.9318rem + 0.3409vw, 1.1875rem) : 16 px à 320 px de large, 19 px à 1 200 px. L’échelle de la section précédente, elle, a été calculée pour des fenêtres d’environ 400 à 1 280 px de large.

Heureusement, des outils existent :

  • Utopia.fyi : un outil gratuit. Vous entrez la largeur de fenêtre minimale et maximale, la taille du texte à chaque bout et un rapport entre les tailles ; il calcule toute l’échelle en variables CSS avec clamp(). Il a aussi des calculateurs pour les espacements, la grille et une valeur seule.
  • Min-Max-Value Interpolation, de l’agence 9elements : plus simple, il calcule le clamp() d’une seule valeur, en px ou en rem.
  • Figma : Utopia propose deux extensions Figma, pour que les designers préparent les mêmes échelles que les développeurs.

Conseil : ne devinez pas les valeurs, utilisez un générateur. Il évite les erreurs de calcul. Vérifiez seulement la taille de base qu’il utilise : 1rem vaut 16 px par défaut, et un outil réglé sur 10 px donnera d’autres tailles.

Calculateur clamp() réglé de 320 à 1 366 px et de 1 à 5 rem, qui donne clamp(1rem, -0.224rem + 3.824vw, 5rem)
Exemple de calculateur réglé sur une taille de base de 10 px (62,5 %) : vérifiez ce réglage avant de copier la formule. Avec la base par défaut de 16 px, ce clamp() irait de 16 à 80 px : un maximum 5 fois plus grand que le minimum, au-delà du repère de 2,5 vu plus haut.

8. Quand ne pas utiliser clamp() ?

Malgré mon enthousiasme, clamp() n’est pas la solution à tout. Il est important de savoir quand revenir aux bonnes vieilles méthodes.

  1. Changements de mise en page : clamp() gère des valeurs (taille, largeur, espacement), pas la disposition. Pour passer de 3 colonnes à 1, il faut Grid ou Flexbox, avec une media query, une requête de conteneur (container query), ou une grille qui s’adapte seule (exemple ci-dessous).
  2. Lisibilité critique : parfois, une taille ne doit pas être fluide. Pour des textes juridiques ou des interfaces denses (tableaux de données), une taille fixe en rem est souvent préférable. Évitez le px pour le texte : il ne suit pas la taille de texte choisie dans les réglages du navigateur (MDN).

Pour le premier cas, voici une grille qui passe seule de 3 colonnes à 1, sans media query :

.cartes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: clamp(1rem, 3vw, 2.5rem);
}

Chaque carte mesure au moins 18rem (288 px), ou toute la largeur sur un écran plus étroit, et le navigateur place autant de colonnes que la place le permet (repeat() et auto-fit). Avec trois cartes : 1 colonne sur un téléphone de 375 px, 2 à 768 px de large, 3 à 1 024 px.

9. Compatibilité avec les navigateurs

C’est souvent la question qui fâche : « C’est génial, mais est-ce que ça marche sur Safari ? »

La réponse est un grand oui.

clamp(), min() et max() fonctionnent dans Chrome, Edge, Firefox et Safari depuis 2020. Elles ont le statut « Baseline, largement disponible » depuis janvier 2023 : selon MDN, elles fonctionnent depuis au moins deux ans et demi dans tous les grands navigateurs.
Selon caniuse (octobre 2026), environ 97 % des internautes ont un navigateur qui les comprend.

Et les 3 % restants ?
Si vous devez prendre en charge des navigateurs très anciens (comme Internet Explorer, paix à son âme, ou les versions de Safari pour iPhone d’avant 2020), la solution de repli est simple :

h1 {
  font-size: 2rem; /* Pour les navigateurs sans clamp() */
  font-size: clamp(2rem, 5vw, 4rem); /* Les navigateurs récents gardent celle-ci */
}

Le navigateur ancien ignorera la seconde ligne qu’il ne comprend pas et appliquera la première. Le site ne sera peut-être pas « parfaitement fluide » pour ces utilisateurs, mais il sera parfaitement lisible et fonctionnel. C’est le principe de l’amélioration progressive.

Conclusion : vers un web plus organique

L’arrivée des fonctions mathématiques en CSS marque une rupture. Nous passons d’un design web « adaptatif » (qui s’adapte par paliers comme un escalier) à un design « fluide » (qui coule comme de l’eau).

Adopter clamp(), ce n’est pas juste écrire moins de code. C’est changer de philosophie. C’est accepter que nous ne contrôlons pas la taille de l’écran de l’utilisateur, et qu’il vaut mieux donner au navigateur des instructions flexibles plutôt que des ordres rigides.

En résumé, pourquoi l’adopter aujourd’hui ?

  1. Code plus court : moins de media queries pour les tailles et les espacements.
  2. Maintenance simplifiée : modifiez une valeur à un seul endroit, le changement se propage partout.
  3. Design plus élégant : fini les sauts bizarres à 768 px ou 1 024 px. Le site est beau à 700 px, 850 px ou 1 300 px.
  4. Accessibilité : à condition de mêler rem et vw, de garder un maximum proche du minimum, et de tester au zoom.

Alors, la prochaine fois que vous écrivez @media (min-width...) pour changer une taille de police ou un padding, arrêtez-vous une seconde et demandez-vous : « Est-ce que clamp() ne pourrait pas faire ça mieux ? »

Pour une taille ou un espacement, la réponse est souvent oui.

Sur les sites WordPress que nous construisons avec Etch et Automatic.css, les tailles des titres et des espacements sont déjà fluides : Automatic.css les écrit avec clamp(), en mêlant rem et vw. Vous avez déjà un site ? Demandez notre diagnostic gratuit, avec un compte rendu écrit sous 5 jours ouvrés.

Partager LinkedIn(nouvel onglet) E-mail

Écrit par SébastienFondateur de Wasabi Web Design, designer et développeur web à Arras

Je conçois des sites rapides et bien référencés pour les indépendants, les professions libérales et les PME, et je partage ici ce que j’apprends sur le terrain.

Mon parcours Mes réalisations

Rubrique Web design

Ouvert à de nouveaux projets

Mettez un peu de wasabi dans votre site.

Parlez-moi de votre activité : je vous envoie sous 48 h un devis gratuit et des recommandations concrètes pour vous lancer.

SébastienFondateur de Wasabi Web Design, à Arras