Vérifier le contraste de couleur WCAG en ligne : AA, AAA et texte large

Vérifier le contraste de couleur WCAG en ligne : AA, AAA et texte large

Un ratio de contraste texte/fond insuffisant est l'erreur d'accessibilité la plus fréquente sur le web. Vérifiez AA/AAA en collant deux couleurs, sans plugin ni extension.

13.09.2026
11 min de lecture
Partager cet article:
accessibility
wcag
color-contrast
CSS
Tutoriel

Le contraste : l'erreur d'accessibilité la plus fréquente sur le web

Chaque année, l'audit WebAIM Million (analyse des pages d'accueil les plus visitées) place le contraste de texte insuffisant en tête des échecs WCAG détectés — devant les images sans texte alternatif ou les liens sans libellé. C'est aussi l'un des rares critères d'accessibilité qui se vérifie en quelques secondes, sans lecteur d'écran ni audit complet. Le vérificateur de contraste FastMinify calcule le ratio WCAG 2.2 entre deux couleurs CSS (HEX, RGB, HSL, OKLCH, color() ou couleurs nommées) et affiche immédiatement les verdicts AA/AAA pour texte normal, texte large et éléments non textuels — sans rien envoyer à un serveur. Il va plus loin qu'un simple couple de couleurs : un mode matrice permet de croiser toute une palette de premier plan contre toute une palette d'arrière-plan en un seul passage. Le cluster complet vit sur le hub Couleur & CSS.

Verdicts WCAG 2.2 en direct — AA, AAA et non-texte 3:1 (SC 1.4.11) pour chaque paire de couleurs
Mode matrice jusqu'à 16 couleurs par axe — auditer une palette de design system entière d'un coup
Slider d'opacité — vérifier un texte semi-transparent composité sur son fond réel
Overlay APCA expérimental (candidat WCAG 3) en complément du ratio WCAG 2.2 classique
URL partageable — envoyez le lien exact de la vérification à un designer ou dans une PR
100 % dans le navigateur — aucune couleur de charte graphique n'est transmise à un serveur

Les erreurs de contraste qui reviennent le plus souvent

Le texte gris clair "élégant" sur fond blanc

Un gris #999999 sur blanc affiche un ratio d'environ 2.85:1 — bien en dessous du seuil AA de 4.5:1. C'est pourtant l'un des choix de design les plus courants pour les textes secondaires, placeholders et légendes.

Texte placeholder de formulaire en gris trop clair (souvent < 3:1)
Légendes et métadonnées ("il y a 2h", "250 vues") en gris pâle sur fond clair
Copier un gris "neutre" d'une maquette Figma sans vérifier le ratio réel
Confondre "ça se lit bien sur mon écran" avec un ratio conforme (luminosité, calibration, fatigue visuelle)
Un bouton dans la couleur de marque qui échoue en silence

Les couleurs de marque "douces" (bleu pastel, vert menthe, orange clair) sont souvent choisies pour l'identité visuelle sans jamais être testées avec du texte blanc dessus.

Bouton primaire bleu clair + texte blanc : ratio parfois sous 3:1
État "disabled" qui ressemble visuellement à un état actif mal contrasté
Icônes monochromes sur fond de couleur sans vérifier le contraste non-texte (3:1)
Un seul test sur le bouton par défaut, jamais sur les états hover/focus/disabled
Texte posé sur une image sans scrim

Un titre blanc sur une photo de héros fonctionne sur la zone sombre du ciel, mais devient illisible sur la zone claire du nuage — le contraste varie selon l'endroit de l'image.

Aucun dégradé ou voile (scrim) sombre sous le texte
Texte testé uniquement sur la version desktop de l'image, pas sur le recadrage mobile
Ombre portée légère utilisée comme unique garantie de lisibilité
Image de fond changeante (carousel, image utilisateur) sans contraste garanti
Le focus visible supprimé pour "faire propre"

outline: none sans remplacement casse la navigation clavier — et c'est un contraste non-texte (SC 1.4.11) qui s'applique aussi aux indicateurs de focus, pas seulement au texte.

`outline: none` sans anneau de focus alternatif
Anneau de focus custom trop pâle par rapport au fond (souvent < 3:1)
Focus visible testé uniquement en thème clair, oublié en dark mode
Aucune vérification du contraste des bordures de champs de formulaire

AA, AAA et texte large : quel ratio viser ?

Texte normal : AA (4.5:1) ou AAA (7:1) ?

Le critère WCAG 1.4.3 (Contrast Minimum) impose un ratio d'au moins 4.5:1 pour le texte normal en niveau AA. Le niveau AAA, plus strict (critère 1.4.6), monte l'exigence à 7:1. AA est le niveau visé par la quasi-totalité des obligations légales (RGAA en France, EN 301 549 en Europe, ADA aux États-Unis) ; AAA reste recommandé mais rarement exigé pour l'ensemble d'un site.

AA (4.5:1) : le plancher légal dans la plupart des réglementations d'accessibilité
AAA (7:1) : recommandé pour le contenu critique (formulaires de paiement, contenu médical/juridique)
Un ratio de 21:1 (noir pur sur blanc pur) est le maximum théorique — inutile d'aller au-delà
Un ratio flatteur en apparence (ex. 4.2:1) peut échouer AA de peu — toujours vérifier le chiffre exact, pas l'impression visuelle
Texte large : le seuil descend à 3:1 (AA) / 4.5:1 (AAA)

WCAG définit le "texte large" comme du texte d'au moins 24px (18pt), ou d'au moins 18.67px (14pt) s'il est en gras (graisse ≥ 700). En dessous de ces seuils, le texte est considéré comme normal même s'il paraît visuellement imposant. FastMinify calcule automatiquement le seuil applicable à partir de la taille et de la graisse renseignées.

≥ 24px, n'importe quelle graisse : texte large → AA = 3:1, AAA = 4.5:1
≥ 18.67px ET graisse ≥ 700 (bold) : texte large → mêmes seuils réduits
17px en gras ne compte PAS comme texte large — c'est un piège fréquent
Un titre H1 en 40px profite du seuil réduit ; un badge en 12px bold n'en profite jamais
Contraste non-texte (SC 1.4.11) : 3:1 pour l'interface

Depuis WCAG 2.1, le critère 1.4.11 (Non-text Contrast) impose un ratio d'au moins 3:1 pour les composants d'interface (bordures de champs, cases à cocher, icônes porteuses de sens, indicateurs de focus) contre leur couleur adjacente — pas seulement pour le texte.

Bordure de champ de formulaire non focus : 3:1 minimum contre le fond de la page
Anneau de focus (outline/box-shadow) : 3:1 minimum contre le fond ET contre l'élément
Icônes purement décoratives (sans information) : non concernées par ce critère
Le vérificateur FastMinify affiche ce verdict séparément — un couple peut réussir en non-texte tout en échouant en texte normal

Comment le ratio de contraste est calculé

La formule WCAG : luminance relative, pas juste une différence de teinte

Le ratio WCAG 2.x compare la luminance relative des deux couleurs (une valeur de 0 à 1 dérivée des composantes RVB linéarisées, pondérées 0.2126 pour le rouge, 0.7152 pour le vert, 0.0722 pour le bleu — l'œil humain perçoit le vert bien plus intensément que le bleu). Le ratio final est (L1 + 0.05) / (L2 + 0.05), où L1 est la luminance de la couleur la plus claire. C'est pour cela que deux couleurs "différentes à l'œil" peuvent donner un ratio proche, tandis que deux teintes qui semblent similaires peuvent avoir des luminances très éloignées.

Avant

color: #999999; background: #ffffff; /* Ratio ≈ 2.85:1 → échec AA (texte normal) */

Après

color: #595959; background: #ffffff; /* Ratio ≈ 7.0:1 → réussite AAA (texte normal) */
Résultat entre 1:1 (couleurs identiques) et 21:1 (noir pur / blanc pur)
Le vert pèse plus lourd que le bleu dans la formule — un bleu vif sur blanc échoue souvent plus vite qu'un vert de luminosité équivalente à l'œil
La formule ignore la teinte (hue) perçue — seule la luminance compte pour le ratio WCAG classique
FastMinify accepte HEX, RGB, HSL, OKLCH et color() en entrée et les convertit en sRGB avant calcul (via colorjs.io)
APCA, le candidat pour WCAG 3 (aperçu expérimental)

Le ratio WCAG 2.x a une limite connue : il traite le contraste "noir sur blanc" et "blanc sur noir" de façon symétrique, ce qui ne correspond pas toujours à la perception réelle. APCA (Advanced Perceptual Contrast Algorithm), pressenti pour WCAG 3, prend en compte la polarité (texte clair sur fond sombre vs l'inverse) et la taille de police pour un jugement plus fin. FastMinify propose un overlay APCA optionnel en complément du ratio WCAG 2.2 officiel — pas en remplacement, puisque WCAG 3 n'est pas encore une norme publiée.

APCA retourne un score "Lc" (Lightness Contrast) plutôt qu'un ratio classique
La polarité (normale ou inversée) influence le score — un même couple de couleurs n'a pas le même Lc selon qui est premier plan et qui est fond
À ce jour, seul le ratio WCAG 2.2 (AA/AAA) fait foi pour la conformité légale (RGAA, EN 301 549, ADA)
Utile pour anticiper une future migration vers WCAG 3, pas pour un audit de conformité actuel

Workflow color-contrast-checker : du couple de couleurs à la palette complète

Vérifier une paire de couleurs en quelques secondes

Ouvrez le vérificateur de contraste, collez votre couleur de premier plan et votre couleur de fond dans n'importe quel format CSS (HEX, RGB, HSL, OKLCH, nommée). Le ratio et les badges AA/AAA/non-texte se recalculent en direct. Ajustez la taille et la graisse du texte pour voir le seuil "texte large" s'appliquer automatiquement.

1

Étape 1 — Collez les deux couleurs

Premier plan et arrière-plan, dans n'importe quel format CSS valide. Aucune conversion manuelle nécessaire.

2

Étape 2 — Réglez taille et graisse du texte

16px/400 par défaut (texte normal). Passez à 24px ou 18.67px+bold pour tester un titre — le seuil "texte large" (3:1/4.5:1) s'applique automatiquement.

3

Étape 3 — Lisez le verdict

Ratio exact (ex. 4.87:1), badge AA/AAA/AA-large/échec pour le texte, et verdict séparé pour le contraste non-texte (3:1, SC 1.4.11).

Scénario — auditer un bouton et son état disabled

Un bouton primaire a souvent trois variantes de couleur (normal, hover, disabled) qu'on oublie de tester individuellement.

Testez le texte du bouton sur le fond "normal" — visez AA (4.5:1) minimum
Testez la même paire sur l'état "hover" — la couleur change souvent, le ratio aussi
Testez l'état "disabled" séparément — un ratio faible y est acceptable si l'état est réellement non interactif et annoncé comme tel (aria-disabled)
Vérifiez la bordure du bouton (si visible) contre le fond de page — c'est un contraste non-texte, seuil 3:1
Mode matrice : auditer toute une palette d'un coup

Plutôt que de tester une à une les combinaisons d'un design system, collez votre liste de couleurs de texte en lignes et votre liste de couleurs de fond en colonnes (jusqu'à 16 couleurs par axe). Le résultat affiche une grille avec le verdict de chaque croisement, filtrable par niveau de conformité (AAA / AA / AA-large / échec).

Utile pour valider tous les tokens de couleur d'un design system en une seule passe
Filtre par niveau : isolez rapidement les seules combinaisons qui échouent
Détecte les couples "limites" (ex. 4.4:1, juste sous le seuil AA) qu'un test manuel couple par couple laisserait facilement passer
Fonctionne avec les mêmes formats de couleur que le mode paire (mélange HEX/RGB/HSL possible dans une même liste)
Partager une vérification avec votre équipe

Chaque vérification (couleurs, taille de texte, mode matrice ou paire, options APCA) est encodée dans l'URL. Copiez le lien depuis la barre d'adresse et collez-le dans une pull request, un ticket ou un message à votre designer — la page se rouvre exactement dans le même état.

Aucune donnée stockée côté serveur — l'état vit entièrement dans les paramètres d'URL
Pratique pour documenter un échec de contraste détecté en review
Le lien reste valide indéfiniment tant que l'outil est en ligne

Faire du contraste un critère de CI, pas juste un aller-retour design

Automatiser la détection avec axe-core ou Lighthouse CI

Un vérificateur manuel est parfait pour concevoir une palette ; pour éviter les régressions, le contraste doit aussi être vérifié automatiquement à chaque pull request. axe-core et Lighthouse CI détectent la plupart des échecs de contraste sur du texte statique (ils ont plus de mal avec le texte sur image ou les dégradés).

Exemple de base

// axe-core avec Playwright — échoue le test si contraste insuffisant import { test, expect } from '@playwright/test' import AxeBuilder from '@axe-core/playwright' test('pas de régression de contraste', async ({ page }) => { await page.goto('/') const results = await new AxeBuilder({ page }) .withTags(['wcag2aa']) .analyze() const contrastIssues = results.violations.filter( (v) => v.id === 'color-contrast' ) expect(contrastIssues).toEqual([]) })
FastMinify color-contrast-checker

Vérification manuelle rapide, sans installation ni donnée envoyée. Le mode matrice, unique parmi ces options, permet d'auditer un design system complet en un seul passage, et l'URL partageable facilite la collaboration entre designers et développeurs. Limite : c'est une vérification manuelle qui ne remplace pas un audit automatisé en CI, et elle ne détecte pas le contraste sur une image ou un dégradé complexe.

DevTools du navigateur (Chrome/Firefox)

L'inspecteur de couleur intégré affiche le ratio de contraste directement sur l'élément sélectionné dans la page réelle, avec les styles calculés — aucun outil externe nécessaire. Limite : un élément à la fois, ce qui devient fastidieux sur une palette complète, sans mode matrice ni partage par lien.

axe-core / Lighthouse CI

Un audit automatisé intégré au pipeline CI détecte systématiquement les régressions de contraste à chaque pull request, et couvre l'accessibilité au-delà du seul contraste. Limite : il ne remplace pas la phase de conception de la palette en amont, et peut produire des faux négatifs sur du texte superposé à une image.

Conclusion

Le contraste de couleur reste l'erreur d'accessibilité la plus fréquente sur le web — et l'une des plus simples à corriger une fois détectée. AA (4.5:1) pour le texte normal, 3:1 pour le texte large et les éléments non textuels : trois chiffres à retenir avant de valider une palette. Le vérificateur de contraste FastMinify donne le verdict instantanément, en mode paire ou en mode matrice pour tout un design system, sans jamais transmettre vos couleurs de marque à un serveur. Combinez-le avec un audit axe-core en CI pour éviter les régressions, et avec le reste du hub Couleur & CSS pour construire une palette cohérente de bout en bout.

Visez AA (4.5:1) en texte normal, 3:1 en texte large et sur les éléments non textuels (bordures, focus, icônes)
Testez tous les états d'un composant interactif — normal, hover, focus, disabled — pas seulement l'état par défaut
Utilisez le mode matrice pour valider un design system complet plutôt que couple par couple
Ajoutez axe-core ou Lighthouse CI en pipeline pour éviter toute régression de contraste après la mise en prod
Le ratio WCAG 2.2 fait foi légalement aujourd'hui — traitez APCA comme un aperçu du futur, pas comme une référence de conformité
Partager cet article
Partager cet article: