Le zoom et l'agrandissement
Le texte doit rester lisible agrandi à 200 %, et le contenu utilisable dans une fenêtre de 320 px. Ce qui casse presque toujours : une hauteur fixe en pixels. Démo mesurée, code, critères RGAA.
3 critères RGAA en jeu
Essayez-le
Les critères non applicables sont exclus du calcul : le taux ne rapporte que les critères applicables.
Les critères non applicables sont exclus du calcul : le taux ne rapporte que les critères applicables.
Fenêtre demandée à 0 px, mesurée à 0 px ; texte à 100 %.
- Hauteur fixe : texte entier, rien hors de la fenêtre.
- Hauteur libre : texte entier, rien hors de la fenêtre.
Les deux cartes portent le même texte. Réglez l’agrandissement à 200 % : celle du haut le perd, parce que sa hauteur est fixée en pixels. Ramenez la fenêtre à 320 px : elle sort du cadre, parce que sa largeur minimale l’est aussi.
Le relevé n’est pas écrit d’avance, il mesure le DOM — zoomez la page entière avec Ctrl + + et regardez les chiffres bouger sans que vous ayez touché à un réglage.
Cette démo existe aussi en page autonome.
L’erreur courante
Une carte dessinée pour un texte connu d’avance, à la taille où on l’a vue.
/* À ne pas faire */
.carte {
height: 112px; /* la boîte ne suivra pas le texte */
overflow: hidden; /* et ce qui dépasse disparaît sans trace */
min-width: 380px; /* et la colonne refusera de se réduire */
font-size: 14px;
} À 100 %, sur l’écran du concepteur, tout tient. À 200 %, le texte occupe le double de hauteur dans une boîte qui n’a pas bougé : la dernière ligne — souvent celle qui porte le montant, la date ou la consigne — est simplement effacée de l’écran. Rien ne l’annonce, aucune barre de défilement n’apparaît, et le texte reste dans le DOM : un test au lecteur d’écran ne verra rien.
Le min-width: 380px produit l’autre moitié du défaut. Dans une fenêtre de
320 px — ou à 400 % de zoom sur un écran ordinaire, ce qui revient au même — la
carte dépasse, et chaque ligne se lit désormais en deux gestes : avancer, puis
revenir.
Et la déclaration qui ferme la porte avant même qu’on essaie :
<!-- À ne pas faire -->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> Soyons exacts sur ce que le RGAA en dit : le critère 10.4 juge le résultat de l’agrandissement, et il admet trois voies — l’agrandissement du texte, le
zoom graphique, un composant du site. Sur un navigateur de bureau qui ignore
l’attribut, le texte grandit quand même, et le test peut passer. La
non-conformité se constate en agrandissant, pas en lisant la balise. Mais user-scalable=no retire le zoom partout où il est honoré, c’est-à-dire sur les
téléphones, et il n’existe aucune raison de le garder.
Trois variantes du même oubli :
line-heighten pixels : l’interligne ne suit plus la police, et les lignes se chevauchent dès le premier cran d’agrandissement.overflow: hiddenposé pour masquer un débordement d’un pixel : il masquera aussi les trois lignes de trop, le jour où elles arrivent.- Une largeur minimale en pixels sur une grille de mise en page
(
min-width: 960px), souvent héritée d’un composant tiers qu’on n’a pas relu.
Le code, pas à pas
1. min-height, jamais height
.carte {
min-height: 7rem; /* un plancher, pas un plafond */
/* pas d'overflow: hidden */
} C’est la correction qui lève le cas d’échec le plus courant du critère 10.4. Une hauteur minimale donne le rythme visuel qu’on cherchait, et laisse la boîte grandir quand son contenu grandit. Une hauteur fixe promet l’inverse : que le contenu tiendra toujours dans ce qu’on a prévu pour lui.
Si un overflow reste nécessaire, auto plutôt que hidden : le contenu
devient atteignable au défilement au lieu d’être perdu. Une zone défilante doit
alors pouvoir être atteinte au clavier — c’est le rôle de tabindex="0" sur le
conteneur, comme dans la démo ci-dessus.
2. Des unités qui suivent l’utilisateur
:root {
font-size: 100%; /* la taille choisie dans le navigateur, quelle qu'elle soit */
}
.carte {
font-size: 1rem;
padding: 0.75em 0.9em; /* l'espacement grandit avec le texte */
line-height: 1.5; /* sans unité : un multiple de la police */
} rem suit le réglage de taille de police du navigateur ; px l’ignore. Un line-height sans unité se recalcule à chaque taille, un line-height: 21px reste à 21 pixels pendant que les caractères en font 32.
Le rembourrage en em mérite le détour : posé en pixels, il devient
proportionnellement minuscule à 200 %, et le texte finit collé au bord.
3. Une mise en page qui se redistribue
.grille {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
} Le min(100%, 20rem) est le détail qui compte : sans lui, minmax(20rem, 1fr) impose 20 rem même quand la fenêtre en fait moins, et la grille déborde. Avec
lui, la colonne se contente de la place disponible, et la grille tient dans la
fenêtre sans imposer de défilement horizontal — c’est ce que demande le
critère 10.11.
Même principe pour les images et les blocs de code : max-width: 100% sur les
premières, et un conteneur en overflow-x: auto autour des seconds, plutôt
qu’une page entière qui défile de côté.
4. La balise de vue, réduite à l’essentiel
<meta name="viewport" content="width=device-width, initial-scale=1" /> Rien d’autre. Ni user-scalable, ni maximum-scale : ces deux-là n’existent
que pour empêcher quelque chose, et ce qu’ils empêchent est le premier réglage
d’une personne malvoyante.
5. Deux vérifications, pas une
Les deux critères ne se testent pas de la même façon, et l’un ne remplace pas l’autre.
- Agrandir le texte seul à 200 % — le réglage « taille de police » du navigateur, pas le zoom. C’est lui qui révèle les tailles verrouillées en pixels et les hauteurs fixes.
- Rétrécir la fenêtre à 320 px de large, ou zoomer à 400 % sur une fenêtre de 1280 px : c’est la même contrainte, et elle révèle les largeurs minimales.
Le zoom graphique du navigateur agrandit la mise en page entière, proportions comprises. Il montre ce que vit quelqu’un qui grossit tout — mais il ne dit rien de ce qui refuse de grandir.
6. Faut-il vraiment tronquer ?
Quand la maquette impose des cartes de même hauteur, la troncature honnête se compte en lignes, pas en pixels :
.resume {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* trois lignes, quelle que soit leur taille */
overflow: hidden;
} Le bloc grandit alors avec la police, et coupe toujours au même endroit du texte. Reste une condition : le texte complet doit exister ailleurs — sur la page de destination, ou derrière un lien. Une troncature n’est acceptable que si elle ne supprime rien.
Au clavier
Le zoom n’est pas un composant : il n’a pas d’interaction propre, et rien n’est à coder pour le clavier. Ce sont les commandes du navigateur qui l’actionnent, et c’est avec elles que le contrôle se fait.
| Touche | Effet |
|---|---|
| Ctrl / ⌘ + + | Zoom graphique : agrandit la mise en page entière, proportions comprises. |
| Ctrl / ⌘ + 0 | Revient à 100 %. À faire entre deux contrôles, sous peine de mesurer autre chose. |
| Réglage « taille de police » du navigateur | Agrandit le texte seul. C’est cette voie-là qui révèle le plus de défauts. |
| Tab | Dans la démo : atteint les réglages, puis la fenêtre simulée, qui est une zone défilante. |
Ce que le lecteur d’écran restitue
Le texte entier — y compris la part que l’écran ne montre plus : « Les critères
non applicables sont exclus du calcul : le taux ne rapporte que les critères
applicables ». La formulation varie d’un lecteur à l’autre, mais le constat est
le même partout : overflow: hidden rogne l’affichage, pas l’arbre
d’accessibilité.
C’est ce qui rend ce défaut si durable. Un test au lecteur d’écran le déclare sain ; il ne se voit qu’en agrandissant et en regardant. Les personnes concernées, elles, ne sont pas celles qui écoutent la page : ce sont celles qui la grossissent.
Le diagnostic inverse tient en deux phrases. Si vous entendez tout le texte alors que l’écran n’en montre que la moitié, c’est un conteneur qui le rogne. Si vous entendez une alternative là où vous attendiez une ligne de texte, c’est un texte en image — il ne grandira jamais, il deviendra flou, et cela relève du critère 1.8.
Checklist
- Aucune
heighten pixels sur un conteneur de texte ;min-heightsi un plancher est nécessaire. - Aucun
overflow: hiddencapable de rogner du texte ;autosinon, atteignable au clavier. - Polices et espacements en unités relatives ;
line-heightsans unité. - Aucune largeur minimale en pixels sur un conteneur de mise en page.
- La balise de vue sans
user-scalablenimaximum-scale. - Relire la page avec le texte agrandi à 200 %, puis dans une fenêtre de 320 px de large — deux contrôles distincts.
Les critères RGAA en jeu
- Critère 10.4 — Lisibilité du texte agrandi à 200 %
Une hauteur fixe en pixels sur un bloc de texte est le défaut type : le texte grandit, la boîte non, et la fin disparaît sous un débordement masqué.
- Critère 10.11 — Contenus sans double défilement
Ce qui déborde dans une fenêtre de 320 px déborde aussi à fort zoom : une largeur minimale en pixels impose alors de défiler dans les deux directions pour lire une seule ligne.
- Critère 10.12 — Espacement du texte redéfinissable
Le même conteneur à hauteur fixe casse quand la personne augmente l'interligne : c'est le même défaut, déclenché par un réglage que le zoom ne montre pas.
Vérifiez votre composant avec l'extension
Pour aller plus loin
- Critère 10.4 — Lisibilité du texte agrandi à 200 % et 10.11 — Contenus sans double défilement : les deux contrôles, et ce qu’un audit y cherche.
- Critère 10.12 — Espacement du texte redéfinissable : le même conteneur à hauteur fixe, cassé par un autre réglage.
- Les tableaux de données : le cas particulier où le défilement horizontal est prévu par le référentiel.
- « Taille des caractères » au glossaire : la définition que le critère 10.4 emploie.
Sources
- MDN —
font-size— les unités qui suivent les réglages de l’utilisateur, et celles qui les ignorent - WCAG — Understanding 1.4.4 Resize Text — le pourquoi de l’agrandissement à 200 %
- WCAG — Understanding 1.4.10 Reflow — la redistribution à 320 px, et ses cas particuliers
- Adrian Roselli — Responsive Type and Zoom — ce que le zoom fait réellement aux unités CSS