Couleurs et fond en CSS : color, background et dégradés

Parmi les premières propriétés CSS que j'ai manipulées en 2017, le soir après le travail, il y avait la couleur du texte et la couleur de fond. C'est toujours par là que je conseille de commencer : le résultat est immédiat à l'écran, et cela oblige à comprendre deux mécanismes fondamentaux du CSS, la cascade et les notations de couleur. Si vous découvrez tout juste les feuilles de style, je vous recommande de lire d'abord comment donner du style à une page grâce au CSS, puis de revenir ici.

Dans cet article, nous allons voir la propriété color, les différentes façons d'écrire une couleur (mots-clés, hexadécimal, rgb(), hsl() et la notation moderne oklch()), les fonds avec background, les dégradés, le contraste texte/fond et l'adaptation au thème sombre. Tous les extraits de code ont été exécutés et mesurés dans Chrome 151 pendant la rédaction : quand j'annonce un résultat, il a été vérifié dans un vrai navigateur.

La propriété color : changer la couleur du texte

Pour modifier la couleur d'un texte, la propriété CSS est color. Elle se pose sur n'importe quel élément qui contient du texte et se transmet à ses descendants par héritage, comme la plupart des propriétés de mise en forme du texte. Pour passer tous les paragraphes en rouge :

p {
  color: red;
}

Ici red est un mot-clé. Le navigateur le convertit en interne : sur ce paragraphe, la valeur calculée que j'ai relevée avec les outils de développement est rgb(255, 0, 0). Ce détail a son importance, car toutes les notations que nous allons voir maintenant sont différentes façons d'écrire la même chose.

Les notations de couleur

Les mots-clés

CSS définit environ 150 noms de couleurs standardisés, en anglais : red, green, blue, orange, tomato, rebeccapurple... C'est pratique pour prototyper, mais trop limité pour un vrai design : impossible d'obtenir exactement le bleu de votre maquette avec un mot-clé.

La notation hexadécimale

La plus répandue. Elle commence par un # suivi de six caractères : deux pour le rouge, deux pour le vert, deux pour le bleu, chacun entre 00 et FF (0 à 255 en base 16, d'où le nom hexadécimal). Le rouge pur s'écrit #ff0000. Quand les deux caractères de chaque paire sont identiques, on peut abréger : #f00.

rgb() et hsl()

rgb() prend trois valeurs de 0 à 255 pour le rouge, le vert et le bleu. hsl() décrit la même couleur autrement : une teinte en degrés sur la roue chromatique (0 = rouge, 120 = vert, 240 = bleu), une saturation et une luminosité en pourcentage. La syntaxe moderne sépare les valeurs par des espaces, sans virgules :

.rouge-rgb {
  color: rgb(255 0 0);
}

.rouge-hsl {
  color: hsl(0 100% 50%);
}

J'ai vérifié ces quatre écritures côte à côte dans Chrome pendant la rédaction : red, #ff0000, rgb(255 0 0) et hsl(0 100% 50%) produisent toutes exactement la même valeur calculée, rgb(255, 0, 0). L'ancienne syntaxe à virgules, rgb(255, 0, 0), reste valide : vous la croiserez dans énormément de code existant.

oklch(), la notation moderne

oklch() est la notation la plus récente, supportée par tous les navigateurs majeurs depuis 2023 (le test CSS.supports('color', 'oklch(62.8% 0.258 29.23)') renvoie true dans mon Chrome). Elle décrit une couleur par sa luminosité perçue, son intensité (chroma) et sa teinte :

.rouge-oklch {
  color: oklch(62.8% 0.258 29.23);
}

Son grand intérêt par rapport à hsl() : la luminosité correspond à ce que perçoit l'œil humain. Deux couleurs oklch() avec la même valeur de luminosité paraissent aussi claires l'une que l'autre, ce qui est faux en HSL (un jaune et un bleu à 50 % de luminosité HSL ne semblent pas du tout aussi lumineux). Pour débuter, l'hexadécimal et rgb() suffisent largement ; retenez simplement qu'oklch() existe et que les outils de design modernes s'en servent pour générer des palettes cohérentes. Autre différence mesurable : Chrome conserve la valeur telle quelle (oklch(0.628 0.258 29.23) en valeur calculée) au lieu de la convertir en RGB.

La transparence avec le canal alpha

Toutes ces notations acceptent une quatrième valeur, le canal alpha, entre 0 (invisible) et 1 (opaque). En syntaxe moderne, elle s'ajoute après une barre oblique :

p {
  color: rgb(255 0 0 / 0.5);
}

Mesuré dans Chrome : la valeur calculée est rgba(255, 0, 0, 0.5), un rouge à 50 % d'opacité qui laisse transparaître le fond derrière le texte. L'ancienne fonction dédiée rgba(255, 0, 0, 0.5) fonctionne toujours, et l'hexadécimal accepte aussi deux caractères de plus pour l'alpha : #ff000080. La transparence est surtout utile sur les fonds : un bandeau semi-transparent au-dessus d'une photo, par exemple.

Couleur de fond : background-color et le raccourci background

Pour colorer l'arrière-plan d'un élément, deux propriétés existent :

Attention à un piège classique quand les deux sont utilisées sur le même élément : ce n'est pas background qui gagne par principe, c'est la déclaration écrite en dernier. J'ai mesuré les deux ordres dans Chrome :

/* Fond calculé : rgb(0, 128, 0), vert */
.exemple-a {
  background-color: red;
  background: green;
}

/* Fond calculé : rgb(255, 0, 0), rouge */
.exemple-b {
  background: green;
  background-color: red;
}

L'explication : le raccourci background réinitialise toutes les sous-propriétés du fond, y compris background-color, avant d'appliquer ses propres valeurs. Écrit après, il écrase donc le rouge ; écrit avant, c'est lui qui se fait écraser. Règle simple pour éviter les surprises : posez le raccourci d'abord, les propriétés spécifiques ensuite.

Les dégradés avec linear-gradient

Un dégradé n'est pas une couleur mais une image générée par le navigateur. Il se pose donc sur background ou background-image, jamais sur color :

.banniere {
  background: linear-gradient(to right, #1d4ed8, #9333ea);
}

Vérifié dans Chrome : la valeur calculée de background-image devient linear-gradient(to right, rgb(29, 78, 216), rgb(147, 51, 234)), un dégradé du bleu vers le violet, de gauche à droite. Le premier paramètre définit la direction : to right, to bottom (la valeur par défaut), to bottom right, ou un angle précis comme 135deg. Vous pouvez ensuite enchaîner autant de couleurs que vous voulez, chacune pouvant être suivie d'une position en pourcentage.

to rightto bottom135deggauche vers droitehaut vers bas (défaut)diagonale
Les trois directions les plus courantes d'un linear-gradient.

Image de fond et propriétés associées

Pour placer une vraie image en arrière-plan, on utilise background-image avec la fonction url(). Contrairement à une image insérée avec la balise img, une image de fond est purement décorative : elle ne fait pas partie du contenu de la page.

body {
  background-image: url("textures/papier.jpg");
  background-repeat: no-repeat;
  background-position: top right;
  background-attachment: fixed;
}

Trois propriétés complémentaires pilotent son comportement :

Le raccourci background permet de tout regrouper sur une ligne, et même d'empiler plusieurs fonds séparés par des virgules, le premier cité étant affiché au-dessus :

body {
  background:
    url("eclair.png") no-repeat top right,
    url("pluie.png") repeat;
}

Contraste texte/fond : pensez accessibilité

Choisir une couleur de texte et une couleur de fond, c'est aussi une question de lisibilité. Le référentiel d'accessibilité WCAG exige un rapport de contraste d'au moins 4,5:1 entre le texte et son fond pour du texte de taille normale (3:1 pour les gros titres). Ce rapport va de 1:1 (aucun contraste) à 21:1 (noir pur sur blanc pur).

Pour rendre cela concret, j'ai calculé le rapport de contraste de trois combinaisons pendant la rédaction, avec la formule officielle WCAG appliquée aux valeurs mesurées dans Chrome :

3:14,5:1 (minimum WCAG)7:12,32gris clair / blanc6,7blanc / bleu14,68gris foncé / blanc1:121:1
Rapports de contraste mesurés, placés sur l'échelle WCAG : sous 4,5:1, le texte courant n'est pas accessible.

Pas besoin de faire le calcul à la main : les outils de développement de Chrome et Firefox affichent le rapport de contraste directement dans la pipette de couleur, avec un indicateur qui signale si le seuil est atteint. Prenez ce réflexe dès maintenant, il coûte trois secondes par couleur choisie.

Adapter les couleurs au thème sombre

Les systèmes d'exploitation proposent tous un thème sombre, et le navigateur transmet cette préférence à vos pages. En CSS, on la détecte avec la media query prefers-color-scheme. L'approche la plus propre consiste à définir ses couleurs dans des variables CSS, puis à ne redéfinir que les variables dans la media query :

:root {
  --bg: #ffffff;
  --text: #1f2937;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #111827;
    --text: #e5e7eb;
  }
}

body {
  background-color: var(--bg);
  color: var(--text);
}

J'ai testé cette page dans Chrome pendant la rédaction en basculant l'émulation de thème des outils de développement (panneau Rendering, option « Emulate CSS prefers-color-scheme »). En thème clair, le fond calculé du body est rgb(255, 255, 255) et le texte rgb(31, 41, 55) ; en thème sombre, le fond passe à rgb(17, 24, 39) et le texte à rgb(229, 231, 235), sans toucher au HTML ni recharger quoi que ce soit. Les deux paires respectent le contraste minimal vu plus haut : 14,68:1 en clair et 14,33:1 en sombre, valeurs calculées sur les couleurs mesurées.

Pour résumer

Vos couleurs sont posées ; l'étape suivante pour habiller vos blocs, ce sont les bordures et les ombres en CSS. Si un point reste flou, dites-le moi en commentaire. Sam.