</> HTML5Advent
ENFRESDEITPT

// css · Web Platform Advent #21

CSS contrast-color() : texte noir ou blanc automatique, et sa vraie limite

contrast-color() choisit un texte noir ou blanc selon la couleur de fond. La syntaxe, le cas du theming qu'elle résout, le problème des tons moyens signalé par MDN, et le support navigateur.

Un éventail de nuanciers de peinture déplié, chaque bande portant un code couleur

contrast-color() est une fonction CSS qui prend une couleur et renvoie la couleur de texte qui se lit le mieux dessus. Elle est passée dans les quatre moteurs majeurs et est devenue Baseline Newly available en avril 2026. Elle résout un petit problème agaçant que rencontrent sans cesse les interfaces thématisables, et elle a une limite facile à manquer.

Ce qu'elle renvoie vraiment

Deux valeurs seulement : white ou black. Rien d'autre. La fonction compare le contraste des deux avec la couleur passée et renvoie celle qui est la plus élevée. En cas d'égalité exacte, elle renvoie white.

Cette étroitesse est le principe même. Ce n'est pas une fonction générale de dérivation de couleur : elle ne produira ni gris teinté ni nuance proche de votre charte. Elle répond à une seule question : sur ce fond, un texte foncé ou un texte clair se lit-il mieux ?

La syntaxe

Vous passez n'importe quelle valeur <color> valide, y compris une propriété personnalisée :

button {
  background-color: var(--button-color);
  color: contrast-color(var(--button-color));
}

Cette ligne unique est le cas pour lequel elle a été faite. Un composant thématisable reçoit son fond depuis une variable, et la couleur du texte suit automatiquement : plus de seconde variable à maintenir synchronisée, plus de JavaScript qui lit le style calculé.

Des rangées de panneaux d'échantillons de couleurs encadrés de bois, posés debout
Des panneaux d'échantillons en showroom : chaque teinte a besoin d'une étiquette qui reste lisible dessus, exactement le problème que contrast-color() automatise en CSS.

Là où elle est utile

Les thèmes clair et sombre sont le cas le plus net. Définissez le fond une fois par thème et laissez le texte suivre :

:root {
  --background-color: navy;
}

@media (prefers-color-scheme: light) {
  :root {
    --background-color: wheat;
  }
}

body,
a {
  background-color: var(--background-color);
  color: contrast-color(var(--background-color));
}

Le même motif marche pour une couleur d'accent choisie par l'utilisateur, des étiquettes colorées par catégorie, et toute bibliothèque de composants où l'intégrateur passe un fond que vous ne pouvez pas prévoir. Avant cette fonction, la réponse habituelle était une table fond-vers-texte maintenue à la main, ou un calcul au build.

La limite à connaître

MDN publie un avertissement explicite à ce sujet, et il mérite d'être répété : le contraste WCAG AA (4,5:1) n'est pas atteignable sur tous les fonds. Les tons moyens échouent généralement face au noir comme au blanc. L'exemple documenté est un bleu roi, #2277d3 : contrast-color() renvoie du noir, et ce noir sur ce bleu n'est pas lisible en petit corps.

La fonction vous dit donc laquelle des deux options est la meilleure, pas que le résultat est suffisant. Sur un fond mi-ton, aucune des deux ne l'est. La règle pratique est celle que donne MDN : utilisez-la avec des couleurs franchement claires ou franchement foncées, et gardez une vraie vérification de contraste dans votre processus pour tout ce qui est entre les deux.

Si vous doutez qu'un fond tombe dans ce piège des tons moyens, passez-le dans notre vérificateur de contraste WCAG avant de livrer.

Support navigateur

Baseline Newly available depuis avril 2026, c'est-à-dire disponible dans les versions stables actuelles de Chrome, Edge, Firefox et Safari, sur ordinateur et mobile. La nuance entre « Newly » et « Widely » compte : les appareils anciens et les navigateurs non mis à jour ne l'ont pas. Comme la déclaration échoue simplement à l'analyse là où elle n'est pas supportée, une déclaration color placée avant elle dans la même règle sert de repli naturel.

Aide-mémoire

QuestionRéponse
Valeurs de retour possibleswhite ou black uniquement
Égalité entre les deuxrenvoie white
Accepte une propriété personnaliséeoui : contrast-color(var(--c))
Garantit WCAG AAnon : les tons moyens échouent des deux côtés
Statut BaselineNewly available, avril 2026
Replidéclarer color avant elle dans la même règle

Utilisez-la là où le fond est vraiment imprévisible et franchement clair ou foncé. N'en faites pas un substitut au choix de couleurs lisibles dès le départ : elle retient la meilleure de deux options, ce qui n'est pas la même chose que d'en produire une bonne.