Le contraste parfait n'existe pas
Table des matières
Tu as fait le travail, et ça ne suffit pas
Dans Les couleurs mentent, je montrais comment construire un design qui dit la vérité : doubler chaque signal couleur d'un signal textuel, vérifier les ratios de contraste, tester en forced-colors. Tu as peut-être appliqué tout ça. Tu vises AAA, 7:1 partout. Ton validateur est au vert.
Et pourtant, il reste des gens pour qui tes couleurs ne fonctionnent pas.
Prenons l'achromatopsie incomplète. Ces personnes gardent une vision résiduelle des couleurs, mais réduite, et surtout différente d'une personne à l'autre. Certaines distinguent encore une trace de rouge, d'autres un peu de bleu, selon les cônes qui fonctionnent encore. Il n'y a pas une achromatopsie, il y en a autant que de personnes concernées.
Pour elles, le ratio de contraste WCAG ne décrit pas leur réalité. La formule est calculée sur une vision typique, à trois cônes. Deux couleurs que la norme juge parfaitement contrastées peuvent leur apparaître identiques. Et l'inverse est vrai aussi : deux couleurs jugées proches peuvent leur sembler distinctes. Le ratio parfait sur le papier ne garantit rien dans leur perception.
On mesure, on valide, on coche la case. Et il reste des gens pour qui ça ne marche pas, parce qu'aucune mesure statistique ne peut couvrir une perception aussi singulière.
Alors on cherche la couleur magique ? Elle n'existe pas. La vraie réponse, ce n'est pas de mieux choisir. C'est de laisser choisir.
Qui tient le volant
Quand un utilisateur active le mode couleurs forcées, il définit ses propres couleurs : texte, fond, liens. Le navigateur les applique à ton site en contournant ton CSS. Tu le détectes avec forced-colors: active et tu restes cohérent grâce aux mots-clés système comme Canvas ou CanvasText.
La question, c'est : qui fournit ce mécanisme ?
| Environnement | Qui tient le volant | Media query |
|---|---|---|
| Windows — Edge, Chrome, Firefox | L'OS impose les couleurs | forced-colors: active |
| macOS — Firefox | Le navigateur propose le mode (réglage « Couleurs ») | forced-colors: active |
| macOS — Safari, Chrome, Edge | Personne ne force les couleurs | prefers-contrast: more |
| Linux — Firefox, Chromium | L'OS (thème à contraste élevé) ou Firefox | forced-colors: active |
| Android — Chrome, Edge, Firefox | Personne ne force les couleurs | aucun levier fiable |
| iOS — Safari | Personne ne force les couleurs | prefers-contrast: more |
| iOS — Chrome, Firefox, Edge | Personne ne force (moteur WebKit imposé) | prefers-contrast: more |
La ligne de partage n'est pas Windows contre macOS. C'est : qui tient le volant. Sur Windows, l'OS. Sur macOS et Linux avec Firefox, le navigateur. Partout ailleurs, Chrome, Edge, Safari et tout l'écosystème mobile, personne ne force quoi que ce soit.
La dernière ligne du tableau mérite qu'on s'y arrête. Chrome sur iPhone, Firefox sur iPad : ce sont des surcouches autour du moteur WebKit d'Apple. Quelle que soit l'icône sur l'écran d'accueil, c'est Safari qui fait le rendu. Et Safari, l'équipe WebKit le documente noir sur blanc :
La valeur
customdeprefers-contrastne retourne pas "true" sur les plateformes Apple, puisqu'il n'existe aucun mode couleurs forcées dans iOS, iPadOS, macOS ou visionOS.
Chez Safari, une media query non satisfaite s'évalue simplement à faux : forced-colors: active ne sera jamais vraie. Il n'y a rien à activer.
La réglementation européenne (DMA) autorise les moteurs alternatifs sur iOS dans l'Union européenne depuis iOS 17.4. Mais à ce jour, aucun navigateur n'a publié de version utilisant un moteur non-WebKit. La situation du tableau reste donc exacte.
Sur Safari, tout ce que tu reçois, c'est prefers-contrast: more. Pas une palette, juste une intention : "je veux plus de contraste". Et c'est à toi d'y répondre.
Ne pas gêner
Ton rôle n'est pas de choisir le bon contraste. C'est de ne pas empêcher l'utilisateur de choisir le sien.
Pour forced-colors: active
C'est le cas couvert dans Les couleurs mentent. Quand le mode couleurs forcées est actif, le navigateur remplace ta palette. Ton travail, c'est de vérifier que rien d'essentiel ne repose sur ce qu'il ne sait pas remplacer tout seul : une information portée par une background-image, une ombre, une bordure que tu croyais décorative.
Active le mode contraste élevé sur ta machine. Navigue sur ton propre site. Ce que tu verras te surprendra probablement.
Pour prefers-contrast: more
C'est le filet de sécurité pour Safari et pour tout l'écosystème mobile Apple. L'utilisateur ne redéfinit pas tes couleurs, il te dit qu'il en a besoin de meilleures. C'est à toi de répondre, dans ton propre design :
@media (prefers-contrast: more) {
:root {
--color-border: var(--color-text);
--color-bg-subtle: var(--color-bg);
}
.btn-secondary {
border-width: 2px;
}
}Épaissir les bordures, supprimer les fonds subtils qui brouillent la lisibilité, renforcer les séparations visuelles. Pas une refonte, quelques ajustements ciblés qui font la différence pour ceux qui les ont demandés.
Les deux ensemble
Les deux media queries ne s'excluent pas. Elles couvrent des cas différents, et parfois les mêmes : quand Firefox force les couleurs, il positionne aussi prefers-color-scheme et prefers-contrast en fonction du thème choisi, et sur Windows les deux sont actives en même temps. Intègre-les dans ton socle CSS aux côtés de tes autres media queries d'adaptation :
@media (prefers-reduced-motion: no-preference) { /* animations */ }
@media (prefers-contrast: more) { /* … */ }
@media (forced-colors: active) { /* … */ }Si ces lignes sont dans ton socle dès le premier jour, chaque composant que tu construis sera pensé pour y répondre.
Le meilleur contraste, c'est celui qu'on ne décide pas à sa place.
Sources
- WebKit — Features in Safari 18.0 — documentation de l'absence de forced-colors sur plateformes Apple
- Apple Developer — Alternative Browser Engines — cadre DMA pour les moteurs alternatifs sur iOS
- MDN — forced-colors — spécification et compatibilité navigateur
- Polypane — Forced colors explained — guide pratique, dont le mode propre à Firefox
- MDN — prefers-contrast — media query d'intention de contraste
- MDN — CSS system-color — mots-clés système pour forced-colors