Vérificateur de contraste des couleurs
Vérifiez le ratio de contraste WCAG AA et AAA entre la couleur de texte et la couleur de fond
Couleur du texte (premier plan)
Couleur de fond
Exemple de texte grand (18px gras)
Exemple de texte normal — voici comment votre corps de texte apparaîtra sur la couleur de fond que vous avez choisie.
Ratio de contraste
14.63:1
Conformité WCAG
Réussi
Normal AA
Réussi
Normal AAA
Réussi
Grand AA
Réussi
Grand AAA
WCAG AA — Texte normal: 4.5:1, Texte grand (18px+ ou 14px gras): 3:1
WCAG AAA — Texte normal: 7:1, Texte grand (18px+ ou 14px gras): 4.5:1
Qu'est-ce que la vérification de contraste des couleurs ?
La vérification de contraste des couleurs mesure la différence de luminance entre une couleur de premier plan (généralement le texte) et une couleur de fond, puis exprime le résultat sous forme de ratio. Un ratio de 1:1 signifie que les couleurs sont identiques ; 21:1 est le maximum, représentant du noir sur blanc ou vice versa. Les Règles pour l'accessibilité des contenus Web (WCAG), publiées par le W3C, définissent les ratios de contraste minimaux que le texte doit atteindre pour que les personnes malvoyantes ou atteintes de déficiences chromatiques puissent le lire.
La formule du ratio de contraste est issue de WCAG 2.x et repose sur la luminance relative, une mesure de la brillance apparente d'une couleur pour l'œil humain. La luminance relative est calculée en linéarisant chaque canal sRGB (en supprimant le gamma) et en pondérant les canaux selon les coefficients ITU-R BT.709 : 0,2126 pour le rouge, 0,7152 pour le vert et 0,0722 pour le bleu. Le vert contribue le plus car l'œil humain y est le plus sensible. Le ratio est ensuite (L1 + 0,05) / (L2 + 0,05), où L1 est la luminance de la couleur la plus claire.
WCAG définit deux niveaux de conformité. Le niveau AA exige un ratio de contraste d'au moins 4,5:1 pour le texte de taille normale et 3:1 pour le texte grand (18px ou plus, ou 14px en gras). Le niveau AAA relève la barre à 7:1 et 4,5:1 respectivement. WCAG 2.1 a également introduit le Critère de succès 1.4.11, qui exige un ratio de 3:1 pour les composants d'interface non textuels comme les bordures, les icônes et les indicateurs de focus.
Pourquoi utiliser ce vérificateur de contraste ?
Évaluer le contraste à l'œil nu est peu fiable. Des couleurs qui semblent bien distinctes sur votre écran calibré peuvent se fondre l'une dans l'autre sur un écran de piètre qualité, en plein soleil ou pour une personne atteinte de deutéranopie. Un ratio numérique supprime les approximations et vous donne un verdict réussi/échoué par rapport à la norme WCAG.
Cas d'usage du vérificateur de contraste
Exigences de ratio de contraste WCAG
Le tableau ci-dessous résume les ratios de contraste minimaux requis par WCAG 2.1 pour différents types de contenu et niveaux de conformité. Le texte grand est défini comme 18px (24 pixels CSS) ou plus en graisse normale, ou 14px (18,66 pixels CSS) ou plus en gras.
| Niveau | Ratio min. | S'applique à | Note |
|---|---|---|---|
| AA Normal text | 4.5 : 1 | Body text, paragraphs, labels | Minimum for most UI text |
| AA Large text | 3.0 : 1 | Text >= 18px, or >= 14px bold | Minimum for headings |
| AA UI components | 3.0 : 1 | Borders, icons, focus indicators | Non-text contrast (WCAG 1.4.11) |
| AAA Normal text | 7.0 : 1 | Body text at highest standard | Enhanced readability |
| AAA Large text | 4.5 : 1 | Large text at highest standard | Enhanced for headings |
Luminance, AA et AAA expliqués
Le calcul du ratio de contraste comporte trois étapes : calculer la luminance de chaque couleur, dériver le ratio, puis le comparer aux seuils WCAG.
Exemples de code
Calculez les ratios de contraste WCAG de façon programmatique. Chaque exemple implémente la formule de luminance relative issue de WCAG 2.x et le calcul du ratio de contraste. Les mêmes paires noir sur blanc et indigo sur blanc sont testées pour comparaison.
// Calculate relative luminance per WCAG 2.x (sRGB)
function luminance(r, g, b) {
const [rs, gs, bs] = [r, g, b].map(c => {
c /= 255
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
})
return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs
}
// Contrast ratio between two RGB colors
function contrastRatio(fg, bg) {
const l1 = luminance(...fg)
const l2 = luminance(...bg)
const lighter = Math.max(l1, l2)
const darker = Math.min(l1, l2)
return (lighter + 0.05) / (darker + 0.05)
}
contrastRatio([0, 0, 0], [255, 255, 255]) // -> 21.0
contrastRatio([99, 102, 241], [255, 255, 255]) // -> 3.95
contrastRatio([29, 78, 216], [255, 255, 255]) // -> 6.06 (AA pass)def luminance(r: int, g: int, b: int) -> float:
"""Relative luminance per WCAG 2.x, ITU-R BT.709 coefficients."""
channels = []
for c in (r, g, b):
c /= 255
channels.append(c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4)
return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2]
def contrast_ratio(fg: tuple, bg: tuple) -> float:
l1 = luminance(*fg)
l2 = luminance(*bg)
lighter, darker = max(l1, l2), min(l1, l2)
return (lighter + 0.05) / (darker + 0.05)
print(f"{contrast_ratio((0, 0, 0), (255, 255, 255)):.2f}") # -> 21.00
print(f"{contrast_ratio((99, 102, 241), (255, 255, 255)):.2f}") # -> 3.95
# Check WCAG AA for normal text
ratio = contrast_ratio((29, 78, 216), (255, 255, 255))
print(f"{ratio:.2f} — {'AA pass' if ratio >= 4.5 else 'AA fail'}") # -> 6.06 — AA passpackage main
import (
"fmt"
"math"
)
func linearize(c float64) float64 {
c /= 255
if c <= 0.04045 {
return c / 12.92
}
return math.Pow((c+0.055)/1.055, 2.4)
}
func luminance(r, g, b int) float64 {
return 0.2126*linearize(float64(r)) +
0.7152*linearize(float64(g)) +
0.0722*linearize(float64(b))
}
func contrastRatio(fgR, fgG, fgB, bgR, bgG, bgB int) float64 {
l1 := luminance(fgR, fgG, fgB)
l2 := luminance(bgR, bgG, bgB)
lighter := math.Max(l1, l2)
darker := math.Min(l1, l2)
return (lighter + 0.05) / (darker + 0.05)
}
func main() {
ratio := contrastRatio(0, 0, 0, 255, 255, 255)
fmt.Printf("%.2f\n", ratio) // -> 21.00
ratio = contrastRatio(29, 78, 216, 255, 255, 255)
fmt.Printf("%.2f\n", ratio) // -> 6.06 (AA pass for normal text)
}/* WCAG-safe color pairs — tested contrast ratios */
/* 12.63:1 — passes AAA normal text */
.high-contrast {
color: #1e293b; /* slate-800 */
background: #f8fafc; /* slate-50 */
}
/* 7.07:1 — passes AAA normal text */
.dark-theme-text {
color: #e2e8f0; /* slate-200 */
background: #0f172a; /* slate-900 */
}
/* 4.57:1 — passes AA normal, fails AAA */
.accent-on-white {
color: #1d4ed8; /* blue-700 */
background: #ffffff;
}
/* 2.14:1 — fails AA for text, but passes 3:1 for large text */
.muted-heading {
color: #94a3b8; /* slate-400 */
background: #ffffff;
}