Couleur de texte accessible
Corrigez un texte trop peu contrasté sans perdre sa teinte : le gris #888888 sur blanc n’atteint que 3.54 pour 1, il est donc assombri en #767676 pour obtenir 4.54 pour 1, juste au-dessus de la cible de 4.5. Seule la luminosité change. Gratuit dans votre navigateur.
- Gratuit
- Fonctionne dans votre navigateur
- Sans inscription
- Vos données restent sur votre appareil
Lancer gratuitement
Exemple résolu
- Arrière-plan
- #ffffff
- Texte
- #888888
- Ratio cible
- 4,5
- Rapport d'origine
- 3,54
- Rapport suggéré
- 4,54
- Direction
- darken
- Luminosité avant
- 53,33
Ce suggesteur de couleur de texte accessible prend une couleur hexadécimale de fond, une hexadécimale de texte de départ et un rapport de contraste WCAG cible, puis renvoie une couleur de texte suggérée qui atteint ce rapport en ne déplaçant que la luminosité HSL. La teinte et la saturation restent fixes, ainsi un bleu de marque reste bleu tout en s’assombrissant ou s’éclaircissant assez pour réussir AA ou AAA sur la surface donnée. Si la couleur de départ atteint déjà la cible, elle est renvoyée inchangée et marquée comme non ajustée. Les concepteurs, les auteurs de jetons de design et les tâches de CI s’en servent lorsqu’un vérificateur de contraste ne suffit pas : ils ont besoin d’une hexadécimale de remplacement déterministe, pas seulement d’un drapeau de réussite ou d’échec. Il n’y a ni appels réseau, ni graines aléatoires, ni lecture d’horloge.
Comment une recherche de luminosité atteint une cible de contraste WCAG
Le contraste sur le web n’est pas une affaire de goût. Les Règles pour l’accessibilité des contenus Web définissent un seul rapport de contraste à partir de la luminance relative, afin que le corps de texte, les boutons et les libellés restent lisibles pour les personnes malvoyantes.
Ce suggesteur part de votre hexadécimale de fond et d’une hexadécimale de texte de départ, puis ne change que la luminosité de cette couleur de texte en HSL jusqu’à ce que le rapport WCAG 2.x contre le fond atteigne la cible que vous avez demandée. La teinte et la saturation restent en place, ainsi un bleu marine de marque reste marine et un rouge de marque reste rouge ; seule varie la clarté ou l’obscurité de l’encre.
Le moteur linéarise chaque canal sRGB avec la courbe officielle par morceaux, construit la luminance avec les poids 0.2126, 0.7152 et 0.0722, et calcule la luminance plus claire plus 0.05 divisée par la plus sombre plus 0.05. Il parcourt ensuite la luminosité HSL par dixièmes de pour cent déterministes vers le noir et vers le blanc, reconvertit chaque pas en RGB 8 bits et conserve la première hexadécimale quantifiée dans chaque sens qui atteint la cible non arrondie.
Le candidat au plus petit changement de luminosité l’emporte ; une égalité préfère l’assombrissement, correction habituelle pour une typographie grise sur une carte claire. Si la couleur de départ atteint déjà la cible, elle est renvoyée inchangée afin de ne pas réécrire des jetons sans raison. Il n’y a ni jitter aléatoire, ni consultation réseau, ni raccourci lié à la date : les trois mêmes entrées produisent toujours la même hexadécimale suggérée et les mêmes drapeaux de validation.
Où un suggesteur de couleur de texte accessible justifie sa place
Les équipes produit arrivent sur cette page lorsqu’un gris de marque paraît élégant sur une diapositive marketing mais échoue comme corps de texte sur une carte blanche, lorsqu’un thème mode sombre est généré à partir de jetons clairs, ou lorsque les parties juridiques demandent une hexadécimale de remplacement plutôt qu’un avis de capture d’écran. Les concepteurs collent une surface et une encre de départ depuis Figma ou un fichier de jetons et rapportent l’hexadécimale suggérée dans la palette, au lieu de pousser à l’œil un curseur de luminosité.
Les spécialistes QA et accessibilité joignent le rapport d’origine, le rapport suggéré et l’hexadécimale suggérée aux tickets afin que les développeurs corrigent le couple exact. Les équipes contenu et marketing vérifient que les couleurs de campagne ont encore un compagnon de texte licite lorsqu’elles sont posées sur des fonds clairs ou sombres du site. Si vous devez seulement mesurer un couple déjà choisi, utilisez une page de vérificateur de contraste ; cette page possède l’intention de suggérer une couleur de texte qui réussit.
Cas d’usage
Corriger des jetons de corps qui échouent
Devant un gris de marque qui rate l’AA sur une carte blanche, obtenez l’hexadécimale plus sombre la plus proche qui réussit 4.5:1 sans changer la teinte.
Encre pour mode sombre et mode clair
À partir d’une seule couleur de texte de départ, dérivez un compagnon qui réussit sur une surface claire et un compagnon qui réussit sur une surface sombre.
Questions fréquentes
Comment le suggesteur de couleur de texte accessible choisit-il une hexadécimale ?
Il conserve la teinte et la saturation de départ, parcourt la luminosité HSL vers le noir et vers le blanc, et renvoie l’hexadécimale quantifiée la plus proche dont le contraste WCAG 2.x atteint la cible. Une égalité préfère assombrir.
Quels rapports cibles pouvez-vous demander ?
Tout nombre fini de 1 à 21 inclus. La valeur par défaut est 4.5 (AA du texte normal). Utilisez 3 pour l’AA du grand texte et 7 pour l’AAA du texte normal.
Combien coûte le suggesteur de couleur de texte accessible ?
L’outil du navigateur est gratuit et s’exécute en local.
Et si aucune nuance de ma couleur n’atteint la cible ?
Vous recevez quand même l’extrême le plus favorable, noir ou blanc, clairement signalé comme n’atteignant pas la cible. C’est le cas, par exemple, avec AAA 7 pour 1 sur une carte gris moyen.
La teinte de ma couleur de marque va-t-elle changer ?
Non. Teinte et saturation restent fixes, seule la luminosité change : un bleu marine de marque reste bleu marine, simplement plus foncé ou plus clair jusqu’à atteindre le contraste.
Outils associés
Pour les développeurs — accès API
Tout sur cette page est disponible par programmation. Cette section s'adresse aux équipes qui veulent l'intégrer à leurs systèmes ; les autres peuvent simplement utiliser l'outil ci-dessus.
Endpoint
Authentification par jeton Bearer : un seul POST met la tâche en file d’attente, et le résultat vous parvient par webhook ou lien signé.
Appeler depuis votre stack
curl -X POST https://api.kit.forhosting.com/color/suggest-accessible-text \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"background":"#ffffff","text":"#888888"}'const res = await fetch("https://api.kit.forhosting.com/color/suggest-accessible-text", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"background": "#ffffff",
"text": "#888888"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/color/suggest-accessible-text",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"background": "#ffffff",
"text": "#888888"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/color/suggest-accessible-text", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"background":"#ffffff","text":"#888888"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"background":"#ffffff","text":"#888888"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/color/suggest-accessible-text", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Exemple de requête
{
"background": "#ffffff",
"text": "#888888"
}Exemple de réponse
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "color.suggest_accessible_text",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}L’API est asynchrone : chaque appel renvoie un task_id immédiatement, puis vous interrogez l’état à raison d’une requête par seconde.
Tarifs
Le prix est publié, sans tokens ni crédits. Une tâche qui échoue n’est pas facturée.
Limites
max_color_chars | 32 |
Erreurs
| HTTP | Code | Signification |
|---|---|---|
401 | unauthorized | Clé API absente ou invalide : vérifiez l’en-tête Authorization. |
402 | insufficient_balance | Solde insuffisant : rechargez votre compte pour lancer cette tâche. |
404 | unknown_type | Type de tâche inconnu : vérifiez le champ type de votre requête. |
429 | rate_limited | Trop de requêtes : ralentissez la cadence, puis réessayez. |
Notes techniques
Si aucune luminosité de cette teinte n’atteint la cible — par exemple AAA 7:1 sur une carte gris moyen — le moteur renvoie tout de même le meilleur extrême, noir ou blanc, et place meets_target à false afin qu’un pipeline puisse échouer de façon fermée. Les appels API réussis sont facturés à $0.002 par élément ; une entrée invalide n’est pas débitée.
Ce que vous envoyez, ce que vous recevez et comment la validation fonctionne
Envoyez une hexadécimale de fond et une hexadécimale de texte de départ. Les cibles courantes sont 3 pour l’AA du grand texte, 4.5 pour l’AA normal et 7 pour l’AAA normal ; tout nombre fini de 1 à 21 inclus est accepté, car c’est l’intervalle WCAG des couleurs identiques au noir sur blanc. Une courte chaîne formula documente la règle. Un target_ratio facultatif vaut 4.5 par défaut, le seuil AA du texte normal. Le fond accepte aussi l’alias bg ; le texte accepte foreground, fg et color ; target_ratio accepte ratio et target. Les champs manquants, les caractères non hexadécimaux, les formes alpha, les longueurs incorrectes, NaN, Infinity et une cible hors de l’intervalle fermé échouent avec invalid_input et ne sont pas facturés. En cas de succès, la réponse renvoie des échantillons normalisés à six chiffres pour le fond, le texte et la suggestion, avec des chaînes rgb imprimables. original_ratio et suggested_ratio sont arrondis à deux décimales pour l’affichage, tandis que meets_target compare le rapport suggéré non arrondi à la cible, afin qu’un 4.50 imprimé ne puisse masquer un vrai 4.499. adjusted indique si l’hexadécimale a réellement bougé ; direction vaut none, darken ou lighten. lightness_before et lightness_after rendent l’étape HSL auditable. L’objet wcag indique normal_aa, normal_aaa, large_aa et large_aaa du couple suggéré afin qu’un relecteur voie la matrice complète, pas seulement la cible demandée. Associez le formulaire gratuit du navigateur à l’API identique à $0.002 par élément réussi lorsqu’un pipeline de jetons de design a besoin de la même hexadécimale en intégration continue.
Où un suggesteur de couleur de texte accessible justifie sa place
Les ingénieurs branchent le même contrat sur des contrôles de pull request qui réécrivent ou rejettent un jeton si l’AA du texte normal descendrait sous 4.5, et lisent meets_target pour qu’une demande AAA impossible sur gris moyen ne publie pas le noir en silence comme s’il avait réussi. Comme cette capacité est un moteur parse pur, le tarif de l’API est la base publiée de $0.002 par élément réussi et une validation en échec ne consomme pas le solde.
Cas d'intégration
Portes de CI qui ont besoin d’une hexadécimale de remplacement
Appelez l’API depuis des pull requests pour réécrire ou rejeter des jetons lorsque le couple suggéré ne peut toujours pas atteindre la cible WCAG demandée.
Questions techniques
Que se passe-t-il si aucune couleur de texte de cette teinte n’atteint la cible ?
Le moteur renvoie le meilleur entre le noir et le blanc et place meets_target à false. Cela arrive sur certains fonds gris moyen lorsque vous demandez 7:1.
Quels formats de couleur sont acceptés ?
Hexadécimal uniquement : #RGB ou #RRGGBB, avec ou sans dièse initial, sans distinction de casse. rgb(), hsl(), les couleurs nommées et l’hexadécimal alpha sont rejetés avec invalid_input.