Mis à jour 15 juillet 2026

Le piège de l’unité vw

Le titre est parti en production avec font-size: 8vw et rendait superbement sur le téléphone pour lequel il avait été conçu — ≈31px sur un écran de 390px, assuré et parfaitement proportionné. La première capture d’écran depuis un moniteur de bureau racontait une tout autre histoire : à 1920px, le même titre s’affichait à ≈154px, six mots formant un mur de caractères, et sur des moniteurs plus larges il continuait de grandir. Rien n’était cassé, au sens où le navigateur faisait exactement ce qu’on lui avait dit. C’est le piège du vw en une phrase : l’unité fait exactement une chose, et elle ne cesse jamais de la faire.

Les unités viewport brutes échouent comme tailles de police pour quatre raisons mécaniques : vw n’a aucune borne, il ignore à la fois le zoom du navigateur et les préférences de taille de police (un échec WCAG 1.4.4), il fusionne taille et vitesse de croissance en un seul nombre, et lorsque le texte et l’espacement suivent tous le viewport, plus rien sur la page n’est ancré. La correction standard est clamp() avec une expression rem + vw ; le vw brut ne mérite sa place que pour du texte d’affichage plein écran, avec un plancher en rem.

Ce guide est la référence de mise en garde de notre guide de la typographie fluide — ce qui tourne mal, calculé à des largeurs réelles, et la progression des correctifs.

Pourquoi continue-t-on d’écrire des tailles de police en vw ?

Parce que la séduction est réelle. Une seule déclaration — font-size: 4vw — et le texte est parfaitement proportionnel à l’écran : pas de media queries, pas de paliers, pas de tableaux de tailles. Un vw vaut 1 % de la largeur du viewport (voir le guide des unités viewport de web.dev pour la mécanique), donc 4vw se lit comme « du texte qui fait toujours 4 % de l’écran » — ce qui ressemble exactement à ce que la typographie responsive était censée être. Chaque échec ci-dessous n’est que cette même propriété vue sous un angle différent : la proportionnalité parfaite est le problème.

Qu’est-ce qui casse avec des tailles de police en vw pur ?

1. Aucune borne. 4vw vaut ≈14px sur un viewport de 360px et ≈77px à 1920px — les deux depuis la même déclaration. Il n’y a pas de plancher sous la lisibilité sur petits écrans, ni de plafond au-dessus de l’absurde sur les grands. Les autres échecs se discutent ; celui-ci n’est que de l’arithmétique.

2. Insensible au zoom. Le zoom du navigateur met à l’échelle le pixel CSS, ce qui met à l’échelle le texte en px et en rem — mais la largeur CSS du viewport rétrécit du même facteur, si bien qu’une taille basée sur vw se recalcule à la même taille physique. Zoomé à 200 %, le texte en vw pur ne grandit pas du tout, et il ignore la préférence de taille de police du navigateur pour la même raison. C’est un échec WCAG 1.4.4. (Toute l’arithmétique du zoom rem-contre-vw est un sujet à part entière ; en une ligne : seule la part en rem d’une taille fluide répond au zoom.)

3. Pente verrouillée. Avec du vw brut, la taille à une largeur donnée et la vitesse de croissance sont le même nombre. Vous voulez du texte courant à 16px sur un téléphone de 360px ? Cela fait 16 / 360 × 100 ≈ 4,44vw. Mais 4,44vw continue de croître au même rythme pour chaque pixel de viewport supplémentaire, atteignant ≈85px à 1920px. Vous ne pouvez pas dire « 16px sur les téléphones, puis une montée douce à partir de là » — choisir la taille a choisi la pente, et la pente est déchaînée.

4. Tout est proportionnel, rien n’est ancré. La même logique est ensuite appliquée au padding et aux marges (« ils suivent l’échelle, donc ils s’accordent »), et la page devient une maquette à l’échelle : à chaque largeur, la même affiche, photographiée de plus près ou de plus loin. Les proportions texte/espace ne s’adaptent jamais, la densité d’information n’augmente jamais sur les grands écrans — un moniteur de bureau montre la mise en page du téléphone, agrandie. Une page où tout est proportionnel au viewport est indiscernable d’un design de téléphone zoomé.

Que rend réellement 4vw ?

Le tableau qui plaide la cause — 4vw brut face à un clamp borné construit pour le même travail (un titre d’affichage censé se lire à ≈28px sur téléphone et plafonner à 48px) :

Viewportfont-size: 4vwclamp(1.75rem, 1.4615rem + 1.2821vw, 3rem)
320px12,8px28px (le min tient)
360px14,4px28px
768px≈30,7px≈33,2px
1280px51,2px≈39,8px
1920px76,8px48px (le max tient)

Là où les deux colonnes concordent à peu près — autour de la fin des 700 — se trouve le genre de largeur où 4vw « semblait juste » dans le navigateur de quelqu’un pendant le développement. Partout ailleurs elles divergent, et c’est la colonne clamp qu’un designer validerait à chaque ligne.

La deuxième colonne, en direct : ouvrez une configuration fluide bornée dans Scale Composer — le mode fluide est défini par quatre nombres (la base à vp-min, la base à vp-max, et les deux viewports), et l’export CSS écrit chaque valeur fluide sous forme de clamp avec sa plage de pixels réelle en commentaire : les bornes que 4vw n’a jamais eues, rendues explicites.

Une configuration de typographie fluide bornée dans Scale Composer, exportée en valeurs clamp() avec des plages de pixels en commentaire

Comment clamp() corrige-t-il chaque échec ?

Les correctifs s’empilent, un par échec :

  • Bornes : clamp(min, …, max) rétablit un plancher et un plafond — les catastrophes des petits écrans et des écrans géants deviennent les deux zones plates de la courbe.
  • Zoom : l’expression préférée mêle rem et vw. Dans le clamp du tableau, l’essentiel de la taille en milieu de plage provient du terme en rem, si bien que le zoom atteint la majeure partie du texte.
  • Pente : l’ordonnée à l’origine et la pente sont deux nombres indépendants. « 16px à 360px et une montée douce » devient exprimable : le terme en rem fixe l’ancre, le terme en vw fixe le rythme.
  • Ancrage : l’architecture du clamp sur la racine — un seul clamp fluide sur la taille de police racine, tout le reste en rem qui la suit — met à l’échelle le texte et l’espacement sur une seule pente partagée, tandis que les bordures et la géométrie fine restent en px. La page respire ; elle ne zoome pas.

Quand les unités viewport pour la taille de police sont-elles légitimes ?

Une seule exception, énoncée précisément : du texte d’affichage plein écran — une accroche hero, un chiffre d’affiche — où une mise à l’échelle façon affiche est la véritable intention de design, et seulement avec un plancher en rem :

font-size: max(2rem, 6vw);

Le max() garantit que le texte ne s’affiche jamais en dessous de 2rem, et sous un zoom profond, le viewport CSS qui rétrécit cède le contrôle au plancher en rem, si bien que le texte n’est pas insensible au zoom en permanence. Sur la plage normale, il continue de se mettre à l’échelle comme une affiche — ce qui est ici l’objectif. Ce compromis est défendable pour quelques mots d’affichage ; c’est un mauvais compromis pour des titres dans du contenu courant, et pas de compromis du tout pour du texte courant.

Remplacez le nombre qui cumulait deux rôles

Portez la leçon du tableau dans l’outil : chargez la configuration bornée et changez un paramètre à la fois — augmentez la base à vp-max et regardez les commentaires de plage de pixels de l’export suivre pendant que le plancher reste immobile. La taille et la pente qui bougent indépendamment, c’est toute la réparation : 4vw était un seul nombre qui cumulait deux rôles, et clamp() est la rétrogradation dont il avait besoin.

Continuer la lecture

  • Typographie fluide et WCAG 1.4.4 : le test de zoom

    L'accessibilité de la typographie fluide repose sur la répartition rem/vw dans clamp(). Pourquoi le zoom a besoin du terme rem, le protocole de test à 200 % et les chiffres qui passent WCAG 1.4.4.

  • CSS clamp() expliqué avec des chiffres réels

    La fonction CSS clamp() expliquée en calculant intégralement un exemple réel — pente, ordonnée à l'origine et la valeur préférée vw + rem — vérifiée à 360px, 800px et 1280px.