Maîtriser tous les formats de couleurs, créer des palettes accessibles, implémenter le dark mode et manipuler les couleurs avec les fonctions modernes du CSS.
TYPES DE COULEURS CSS ━━━━━━━━━━━━━━━━━━━━━ ┌── NOMMÉES ─────────────────────────┐ │ red, blue, tomato, rebeccapurple │ │ 148 couleurs nommées standard │ └─────────────────────────────────────┘ ┌── HEXADÉCIMALES ───────────────────┐ │ #ff0000 → 6 chiffres hex │ │ #f00 → 3 chiffres (raccourci)│ │ #ff000080 → 8 chiffres (avec alpha)│ └─────────────────────────────────────┘ ┌── RGB / RGBA ──────────────────────┐ │ rgb(255 0 0) │ │ rgb(255 0 0 / 0.5) │ └─────────────────────────────────────┘ ┌── HSL / HSLA ──────────────────────┐ │ hsl(0 100% 50%) │ │ hsl(0 100% 50% / 0.5) │ └─────────────────────────────────────┘ ┌── HWB ─────────────────────────────┐ │ hwb(0 0% 0%) │ └─────────────────────────────────────┘ ┌── ESPACES MODERNES ────────────────┐ │ oklch(0.6 0.2 25) │ │ oklab(0.5 -0.1 0.1) │ │ lab(50 40 -20) │ │ lch(50 45 340) │ └─────────────────────────────────────┘ ┌── FONCTIONS ───────────────────────┐ │ color-mix() light-dark() │ │ color() currentColor │ └─────────────────────────────────────┘
Inventaire complet des formats de couleurs CSS
/* Les 148 couleurs nommées du CSS */
.texte-rouge { color: red; }
.fond-vert { background-color: green; }
.bordure-bleue { border-color: blue; }
/* Les plus utiles */
.link { color: currentColor; } /* Couleur héritée */
.transparent { background: transparent; } /* Valeur spécifique */
.invisible { visibility: hidden; }
/* Exemples moins connus mais utiles */
.titel { color: tomato; } /* Rouge doux */
.accent { color: rebeccapurple; } /* Violet élégant */
.subtle { color: slategray; } /* Gris bleuté */
.warning { color: darkorange; } /* Orange vif */
.success { color: seagreen; } /* Vert naturel */
.info { color: steelblue; } /* Bleu professionnel */
| Format | Pros | Cons | Quand l'utiliser |
|---|---|---|---|
| Nommées | Lisible, rapide à écrire | Peu précises, 148 limitées, pas de variation | Prototypage rapide, cas simples |
/* Syntaxe HEX — notation la plus répandue */
.rouge-6 { color: #ff0000; } /* 6 chiffres : #RRGGBB */
.rouge-3 { color: #f00; } /* 3 chiffres : #RGB (raccourci) */
.rouge-8 { color: #ff000080; } /* 8 chiffres : #RRGGBBAA (avec alpha) */
.rouge-4 { color: #f008; } /* 4 chiffres : #RGBA */
/* Les 3 formats sont équivalents : */
.c1 { color: #ff6347; } /* version 6 */
.c2 { color: #f64; } /* version 3 → même chose */
/* Pas de sensibilité à la casse */
.c3 { color: #FF6347; } /* ✅ Identique */
.c4 { color: #ff6347; } /* ✅ Identique */
/* Exemples pratiques */
.primaire { background: #2563eb; }
.secondaire { background: #7c3aed; }
.succes { background: #16a34a; }
.erreur { background: #dc2626; }
.fond { background: #f8fafc; }
.texte { color: #1e293b; }
.muted { color: #64748b; }
| Format | Pros | Cons | Quand l'utiliser |
|---|---|---|---|
| HEX | Compact, universel, outils de design l'utilisent | Non intuitif, pas de alpha en 3/6 chiffres, difficile de varier la luminosité | Design tokens existants, copier depuis Figma/Photoshop |
/* rgb() — rouge, vert, bleu (0-255 ou 0%-100%) */
.primaire {
background: rgb(37, 99, 235); /* Ancienne syntaxe (virgules) */
background: rgb(37 99 235); /* Nouvelle syntaxe (espaces) */
background: rgb(14.5% 38.8% 92.2%);/* Avec pourcentages */
}
/* Avec alpha (transparence) */
.demi-transparent {
background: rgba(37, 99, 235, 0.5); /* Ancienne syntaxe */
background: rgb(37 99 235 / 0.5); /* Nouvelle syntaxe */
}
/* Opacité variations */
.opacite-10 { background: rgb(37 99 235 / 0.1); }
.opacite-20 { background: rgb(37 99 235 / 0.2); }
.opacite-50 { background: rgb(37 99 235 / 0.5); }
.opacite-80 { background: rgb(37 99 235 / 0.8); }
hsl() représente les couleurs avec la teinte (hue), la saturation et la luminosité. C'est le format le plus intuitif pour créer des variantes d'une couleur.
/* hsl(teinte, saturation%, luminosité%) */
.primaire {
color: hsl(217, 91%, 60%);
color: hsl(217 91% 60%); /* Nouvelle syntaxe */
}
/* Avec alpha */
.demi {
background: hsl(217, 91%, 60%, 0.5);
background: hsl(217 91% 60% / 0.5); /* Nouvelle syntaxe */
}
/* Créer une palette à partir d'une teinte unique */
:root {
--hue: 217;
--sat: 91%;
}
.primary-50 { background: hsl(var(--hue) var(--sat) 97%); }
.primary-100 { background: hsl(var(--hue) var(--sat) 94%); }
.primary-200 { background: hsl(var(--hue) var(--sat) 86%); }
.primary-300 { background: hsl(var(--hue) var(--sat) 76%); }
.primary-400 { background: hsl(var(--hue) var(--sat) 66%); }
.primary-500 { background: hsl(var(--hue) var(--sat) 57%); } /* Base */
.primary-600 { background: hsl(var(--hue) var(--sat) 46%); }
.primary-700 { background: hsl(var(--hue) var(--sat) 39%); }
.primary-800 { background: hsl(var(--hue) var(--sat) 31%); }
.primary-900 { background: hsl(var(--hue) var(--sat) 22%); }
/* Teintes autour du cercle chromatique */
.rouge { color: hsl(0, 90%, 55%); } /* 0° */
.orange { color: hsl(25, 90%, 55%); } /* 25° */
.jaune { color: hsl(48, 90%, 55%); } /* 48° */
.vert { color: hsl(142, 70%, 45%); } /* 142° */
.bleu { color: hsl(217, 91%, 60%); } /* 217° */
.violet { color: hsl(270, 80%, 60%); } /* 270° */
.rose { color: hsl(330, 80%, 60%); } /* 330° */
| Format | Pros | Cons | Quand l'utiliser |
|---|---|---|---|
| HSL | Intuitif, facile de créer des variantes (luminosité) | Pas perceptuellement uniforme (hsl(50,100%,50%) est beaucoup plus lumineux que hsl(250,100%,50%)) | Création de palettes, quand on comprend le modèle |
/* hwb(teinte blanc% noir%) */
.rouge { color: hwb(0 0% 0%); } /* Rouge pur */
.pastel {
background: hwb(217 0% 0%); /* Bleu pur */
background: hwb(217 40% 0%); /* Bleu pastel (ajout de blanc) */
}
.sombre {
background: hwb(217 0% 40%); /* Bleu foncé (ajout de noir) */
}
/* Avantage de HWB : plus intuitif pour "éclaircir" ou "assombrir" */
.bleu-clair { background: hwb(217 0% 10%); } /* Un peu plus sombre */
.bleu-fonce { background: hwb(217 10% 0%); } /* Un peu plus clair */
/* Avec alpha */
.alpha { background: hwb(0 0% 0% / 0.5); }
oklch() utilise l'espace colorimétrique OKLCH (OK Lightness, Chroma, Hue). C'est le format le plus recommandé pour les palettes modernes car il est perceptuellement uniforme : modifier la luminosité de 0.1 produit un changement perçu identique quelle que soit la teinte.
/* oklch(luminosité chroma teinte) */
/* L : 0 (noir) → 1 (blanc) */
/* C : 0 (gris neutre) → ~0.4 (très saturé) */
/* H : 0-360 (teinte en degrés) */
.bleu { color: oklch(0.62 0.19 250); }
.rouge { color: oklch(0.63 0.25 29); }
.vert { color: oklch(0.72 0.19 142); }
.jaune { color: oklch(0.93 0.18 100); }
.gris { color: oklch(0.55 0 0); }
/* Palette harmonieuse : même chroma, luminosité variable */
:root {
--ok-chroma: 0.15;
--ok-hue: 250;
--ok-50: oklch(0.97 var(--ok-chroma) var(--ok-hue));
--ok-100: oklch(0.93 var(--ok-chroma) var(--ok-hue));
--ok-200: oklch(0.87 var(--ok-chroma) var(--ok-hue));
--ok-300: oklch(0.79 var(--ok-chroma) var(--ok-hue));
--ok-400: oklch(0.70 var(--ok-chroma) var(--ok-hue));
--ok-500: oklch(0.62 var(--ok-chroma) var(--ok-hue));
--ok-600: oklch(0.53 var(--ok-chroma) var(--ok-hue));
--ok-700: oklch(0.44 var(--ok-chroma) var(--ok-hue));
--ok-800: oklch(0.35 var(--ok-chroma) var(--ok-hue));
--ok-900: oklch(0.25 var(--ok-chroma) var(--ok-hue));
}
/* Avec alpha */
.alpha { background: oklch(0.62 0.19 250 / 0.5); }
/* Avantage : créer des variantes sombres/claires est cohérent */
/* En HSL : hsl(50,100%,50%) est très lumineux, hsl(250,100%,50%) est sombre */
/* En OKLCH : une luminosité de 0.6 est TOUJOURS la même intensité perçue */
| Format | Syntaxe | Perceptuellement uniforme | Facilité de variation | Browser support |
|---|---|---|---|---|
HEX |
#2563eb |
Non | Difficile | 100% |
RGB |
rgb(37 99 235) |
Non | Moyenne | 100% |
HSL |
hsl(217 91% 60%) |
Non | Bonne | 100% |
HWB |
hwb(217 0% 0%) |
Non | Bonne | 96%+ |
OKLCH |
oklch(0.62 0.19 250) |
Oui | Excellente | 93%+ |
/* color-mix(in espace-colorimétrique, couleur1 proportion, couleur2 proportion) */
.melange {
/* Mélange 50/50 de bleu et rouge dans OKLCH */
background: color-mix(in oklch, #2563eb 50%, #dc2626 50%);
}
/* Variantes d'une couleur de base */
:root {
--primary: #2563eb;
}
.primary-50 { background: color-mix(in oklch, var(--primary) 10%, white); }
.primary-100 { background: color-mix(in oklch, var(--primary) 20%, white); }
.primary-200 { background: color-mix(in oklch, var(--primary) 30%, white); }
.primary-300 { background: color-mix(in oklch, var(--primary) 40%, white); }
.primary-400 { background: color-mix(in oklch, var(--primary) 50%, white); }
.primary-500 { background: var(--primary); }
.primary-600 { background: color-mix(in oklch, var(--primary) 80%, black); }
.primary-700 { background: color-mix(in oklch, var(--primary) 60%, black); }
.primary-800 { background: color-mix(in oklch, var(--primary) 40%, black); }
.primary-900 { background: color-mix(in oklch, var(--primary) 20%, black); }
/* Transparence avec transparent */
.bleu-20pct {
background: color-mix(in oklch, #2563eb 20%, transparent);
}
/* Hover automatique */
.btn:hover {
background: color-mix(in oklch, var(--btn-bg) 85%, black);
}
.btn:active {
background: color-mix(in oklch, var(--btn-bg) 70%, black);
}
/* Mélanger avec une couleur personnalisée */
.violet {
background: color-mix(in oklch, #2563eb, #7c3aed);
/* Résultat : une teinte entre bleu et violet */
}
/* Espace colorimétrique : in srgb, in hsl, in oklch, in oklab, in lab, in xyz */
.precis { background: color-mix(in oklch, #2563eb 50%, #dc2626); }
.classic { background: color-mix(in srgb, #2563eb 50%, #dc2626); }
/* light-dark(couleur-pour-mode-clair, couleur-pour-mode-sombre) */
/* Nécessite color-scheme sur :root */
:root {
color-scheme: light dark;
}
/* Utilisation */
body {
background: light-dark(#ffffff, #0f172a);
color: light-dark(#1e293b, #e2e8f0);
}
.card {
background: light-dark(#f8fafc, #1e293b);
border: 1px solid light-dark(#e2e8f0, #334155);
box-shadow: light-dark(
0 1px 3px rgba(0,0,0,0.1),
0 1px 3px rgba(0,0,0,0.3)
);
}
.texte-mute {
color: light-dark(#64748b, #94a3b8);
}
/* ⚠️ light-dark() ne fonctionne QUE quand
color-scheme est défini sur un parent ancêtre
avec "light dark" (ou juste "dark") */
CONVERSION ENTRE FORMATS — MÊME COULEUR ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Bleu primaire : #2563eb ┌─────────────────────────────────────────┐ │ HEX #2563eb │ │ RGB rgb(37 99 235) │ │ HSL hsl(217 91% 57%) │ │ HWB hwb(217 15% 8%) │ │ OKLCH oklch(0.62 0.19 250) │ │ OKLAB oklab(0.58 -0.04 -0.12) │ │ LAB lab(47 14 -56) │ └─────────────────────────────────────────┘ Rouge erreur : #dc2626 ┌─────────────────────────────────────────┐ │ HEX #dc2626 │ │ RGB rgb(220 38 38) │ │ HSL hsl(0 72% 51%) │ │ OKLCH oklch(0.60 0.21 25) │ └─────────────────────────────────────────┘
La même couleur exprimée dans différents espaces colorimétriques
MODÈLES DE COULEURS — COMPARAISON
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
RGB/HEX HSL
┌───────────────┐ ┌───────────────┐
│ Rouge (0-255) │ │ Teinte (0-360)│
│ Vert (0-255) │ │ Saturation % │
│ Bleu (0-255) │ │ Luminosité % │
└───────────────┘ └───────────────┘
→ Pas intuitif pour → Plus intuitif
varier la lumière mais pas uniforme
OKLCH HWB
┌───────────────┐ ┌───────────────┐
│ Luminosité │ │ Teinte (0-360)│
│ (0-1, unif.) │ │ Blanc % │
│ Chroma (0-0.4)│ │ Noir % │
│ Teinte (0-360)│ └───────────────┘
└───────────────┘ → Le modèle le
→ Le modèle idéal plus proche de
pour les palettes la perception
humaine
Comparaison des modèles de couleurs CSS
| Niveau | Ratio minimum (texte normal) | Ratio minimum (texte grand) | Description |
|---|---|---|---|
| AA | 4.5:1 | 3:1 | Minimum recommandé — obligation légale dans beaucoup de pays |
| AAA | 7:1 | 4.5:1 | Niveau supérieur — recommandé pour un maximum d'accessibilité |
/* Bonnes pratiques de contraste */
/* ❌ Texte trop faible sur fond clair */
.mauvais {
background: #f8fafc;
color: #cbd5e1; /* Ratio ~1.5:1 — FAIL */
}
/* ✅ Texte suffisamment contrasté */
.bon {
background: #f8fafc;
color: #334155; /* Ratio ~9.5:1 — PASS AAA */
}
/* ✅ Bonne combinaison sur fond coloré */
.bouton-accessible {
background: #2563eb;
color: #ffffff; /* Ratio ~4.6:1 — PASS AA */
}
/* ✅ Pour le texte secondaire (plus petit) */
.texte-secondaire {
background: #ffffff;
color: #475569; /* Ratio ~7:1 — PASS AAA */
}
/* Outils pour vérifier le contraste :
- Chrome DevTools → onglet Accessibility → "Contrast"
- https://webaim.org/resources/contrastchecker/
- Extension axe DevTools */
prefers-color-scheme (automatique) et color-scheme + light-dark() (moderne).
/* Mode clair (par défaut) */
:root {
--bg: #ffffff;
--bg-card: #f8fafc;
--texte: #1e293b;
--texte-muted: #64748b;
--bordure: #e2e8f0;
--primaire: #2563eb;
}
/* Mode sombre — bascule automatique */
@media (prefers-color-scheme: dark) {
:root {
--bg: #0f172a;
--bg-card: #1e293b;
--texte: #e2e8f0;
--texte-muted: #94a3b8;
--bordure: #334155;
--primaire: #60a5fa;
}
}
/* Utilisation */
body { background: var(--bg); color: var(--texte); }
.card {
background: var(--bg-card);
border: 1px solid var(--bordure);
}
a { color: var(--primaire); }
/* Déclarer le support des deux modes */
:root {
color-scheme: light dark;
}
/* light-dark() remplace toutes les variables ! */
body {
background: light-dark(#ffffff, #0f172a);
color: light-dark(#1e293b, #e2e8f0);
}
.card {
background: light-dark(#f8fafc, #1e293b);
border: 1px solid light-dark(#e2e8f0, #334155);
}
a {
color: light-dark(#2563eb, #60a5fa);
}
/* Avantage : pas besoin de variables ni de media query */
/* Le HTML : <html data-theme="sombre"> */
:root[data-theme="sombre"] {
--bg: #0f172a;
--texte: #e2e8f0;
}
:root[data-theme="clair"] {
--bg: #ffffff;
--texte: #1e293b;
}
/* Transition fluide entre les modes */
:root {
transition: background-color 0.3s, color 0.3s;
}
/* JavaScript pour toggle */
<script>
const toggle = document.getElementById('theme-toggle');
toggle.addEventListener('click', () => {
const html = document.documentElement;
const current = html.getAttribute('data-theme');
html.setAttribute('data-theme', current === 'sombre' ? 'clair' : 'sombre');
});
</script>
background: #ffffff
texte: #1e293b
background: #0f172a
texte: #e2e8f0
/* ═══════════════════════════════════════════
NIVEAU 1 — PRIMITIVES (valeurs brutes)
═══════════════════════════════════════════ */
:root {
/* Teintes de base en OKLCH */
--blue-50: oklch(0.97 0.02 250);
--blue-100: oklch(0.93 0.04 250);
--blue-200: oklch(0.87 0.08 250);
--blue-300: oklch(0.79 0.12 250);
--blue-400: oklch(0.70 0.15 250);
--blue-500: oklch(0.62 0.17 250);
--blue-600: oklch(0.53 0.15 250);
--blue-700: oklch(0.44 0.12 250);
--blue-800: oklch(0.35 0.09 250);
--blue-900: oklch(0.25 0.06 250);
--gray-50: oklch(0.98 0.005 250);
--gray-100: oklch(0.96 0.005 250);
--gray-200: oklch(0.92 0.005 250);
--gray-300: oklch(0.87 0.005 250);
--gray-400: oklch(0.71 0.01 250);
--gray-500: oklch(0.55 0.01 250);
--gray-600: oklch(0.45 0.01 250);
--gray-700: oklch(0.37 0.01 250);
--gray-800: oklch(0.27 0.01 250);
--gray-900: oklch(0.20 0.01 250);
--red-500: oklch(0.63 0.25 25);
--green-500: oklch(0.72 0.19 142);
--yellow-500: oklch(0.90 0.18 95);
}
/* ═══════════════════════════════════════════
NIVEAU 2 — SÉMANTIQUE (rôle dans l'UI)
═══════════════════════════════════════════ */
:root {
color-scheme: light dark;
/* Backgrounds */
--bg-primary: light-dark(#ffffff, #0f172a);
--bg-secondary: light-dark(var(--gray-50), var(--gray-900));
--bg-tertiary: light-dark(var(--gray-100), var(--gray-800));
/* Texte */
--text-primary: light-dark(var(--gray-900), var(--gray-50));
--text-secondary: light-dark(var(--gray-600), var(--gray-400));
--text-muted: light-dark(var(--gray-400), var(--gray-500));
/* Interactions */
--interactive: var(--blue-500);
--interactive-hover: var(--blue-600);
--interactive-active: var(--blue-700);
/* États */
--success: var(--green-500);
--error: var(--red-500);
--warning: var(--yellow-500);
/* Bordures */
--border: light-dark(var(--gray-200), var(--gray-700));
--border-subtle: light-dark(var(--gray-100), var(--gray-800));
/* Ombres */
--shadow-sm: light-dark(
0 1px 2px rgba(0,0,0,0.05),
0 1px 2px rgba(0,0,0,0.2)
);
--shadow-md: light-dark(
0 4px 6px rgba(0,0,0,0.07),
0 4px 6px rgba(0,0,0,0.3)
);
}
/* ═══════════════════════════════════════════
NIVEAU 3 — COMPOSANT (propriétés du composant)
═══════════════════════════════════════════ */
.btn {
--btn-bg: var(--interactive);
--btn-text: white;
--btn-radius: 8px;
background: var(--btn-bg);
color: var(--btn-text);
border-radius: var(--btn-radius);
}
.card {
--card-bg: var(--bg-primary);
--card-border: var(--border);
--card-padding: 1.5rem;
background: var(--card-bg);
border: 1px solid var(--card-border);
padding: var(--card-padding);
}
/* ❌ Texte gris très clair sur fond blanc — illisible */
.pied-de-page {
background: #ffffff;
color: #d1d5db; /* Ratio ~1.6:1 — FAIL AAA et AA */
}
/* ✅ Minimum recommandé : ratio 4.5:1 pour AA */
.pied-de-page {
background: #ffffff;
color: #6b7280; /* Ratio ~4.8:1 — PASS AA */
}
/* Vérification avec Chrome DevTools :
Onglet Accessibility → section Contrast → ratio affiché */
/* ❌ "tomato" n'est pas une couleur définie par l'équipe */
.alerte {
background: tomato;
}
/* ✅ Utiliser des tokens sémantiques */
:root {
--error-bg: #fef2f2;
--error-text: #dc2626;
}
.alerte {
background: var(--error-bg);
color: var(--error-text);
}
/* Si tu dois utiliser des couleurs nommées, les
transformer en variables dès le début */
/* ❌ HSL n'est PAS perceptuellement uniforme */
.bleu-500 { color: hsl(217, 91%, 60%); } /* Luminosité 60% */
.vert-500 { color: hsl(142, 70%, 45%); } /* Luminosité 45% */
/* Le vert paraît plus sombre que le bleu malgré la teinte différente,
mais les luminosités ne sont PAS comparables entre teintes */
/* ✅ Avec OKLCH, la luminosité est toujours comparable */
.bleu-500 { color: oklch(0.62 0.19 250); } /* L = 0.62 */
.vert-500 { color: oklch(0.62 0.19 142); } /* L = 0.62 → même luminosité perçue ! */
/* ❌ Les navigateurs anciens ne comprennent pas oklch() */
.bouton {
background: oklch(0.62 0.19 250);
/* Firefox < 113, Chrome < 111 : rien ne s'affiche ! */
}
/* ✅ Fallback obligatoire */
.bouton {
background: #2563eb; /* Fallback */
background: oklch(0.62 0.19 250); /* Navigateurs modernes */
}
/* ✅ Ou utiliser @supports */
@supports (color: oklch(0 0 0)) {
.bouton {
background: oklch(0.62 0.19 250);
}
}
color-mix() pour générer des variantes automatiquement.light-dark() aux media queries pour le dark mode (plus concis).colors.css).Exercice 1 : Palette OKLCH
Crée une palette de 10 nuances (50 à 900) d'une couleur au choix en utilisant uniquement oklch() et des variables CSS. La palette doit être harmonieuse avec une chroma constante.
Exercice 2 : Conversion
Exprime la couleur #dc2626 (rouge d'erreur) dans les 5 formats : HEX, RGB, HSL, HWB et OKLCH. Vérifie que toutes les syntaxes produisent la même couleur visuelle.
Exercice 3 : Contraste WCAG
Vérifie les ratios de contraste de ces combinaisons et classe-les en PASS AA / FAIL AA / PASS AAA / FAIL AAA :
Exercice 4 : Dark mode
Implémente un dark mode complet avec light-dark() pour un site de 3 pages : un header, un sidebar, un contenu principal. Inclure les états hover et les ombres.
Exercice 5 : Système de couleurs complet
Crée un fichier design-tokens.css avec les 3 niveaux (primitives, sémantiques, composants) pour un site e-commerce : produits, panier, catégories, notifications, etc.
Projet : Thème switcher complet
Crée un système de thèmes CSS complet avec :
/* design-system.css — Système complet */
:root {
color-scheme: light dark;
}
/* ═══ PRIMITIVES ═══ */
:root {
/* Teinte bleue — primaire */
--blue-50: oklch(0.97 0.02 250);
--blue-100: oklch(0.93 0.04 250);
--blue-200: oklch(0.87 0.08 250);
--blue-500: oklch(0.62 0.17 250);
--blue-600: oklch(0.53 0.15 250);
--blue-700: oklch(0.44 0.12 250);
/* Teinte neutre */
--gray-50: oklch(0.98 0.005 250);
--gray-100: oklch(0.96 0.005 250);
--gray-200: oklch(0.92 0.005 250);
--gray-400: oklch(0.71 0.01 250);
--gray-600: oklch(0.45 0.01 250);
--gray-800: oklch(0.27 0.01 250);
--gray-900: oklch(0.20 0.01 250);
--white: #ffffff;
/* États */
--red-500: oklch(0.63 0.25 25);
--green-500: oklch(0.72 0.19 142);
}
/* ═══ SÉMANTIQUE ═══ */
:root {
--bg-page: light-dark(var(--white), var(--gray-900));
--bg-card: light-dark(var(--gray-50), var(--gray-800));
--text-1: light-dark(var(--gray-900), var(--gray-50));
--text-2: light-dark(var(--gray-600), var(--gray-400));
--border-1: light-dark(var(--gray-200), var(--gray-800));
--accent: var(--blue-500);
}
/* ═══ COMPOSANTS ═══ */
.btn-primary {
padding: 0.5rem 1.25rem;
background: var(--accent);
color: var(--white);
border: none;
border-radius: 8px;
font-weight: 600;
transition: background 0.15s ease;
}
.btn-primary:hover {
background: color-mix(in oklch, var(--accent) 85%, black);
}
.btn-primary:active {
background: color-mix(in oklch, var(--accent) 70%, black);
}
.card {
background: var(--bg-card);
border: 1px solid var(--border-1);
border-radius: 12px;
padding: 1.5rem;
}
.badge-success {
background: color-mix(in oklch, var(--green-500) 15%, transparent);
color: var(--green-500);
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-weight: 600;
font-size: 0.8rem;
}
Contraintes :
light-dark() ET fallback avec prefers-color-scheme.oklch() pour les primitives et color-mix() pour les hover.Quiz rapide
rgb() et hsl() ?oklch() par rapport à hsl() ?color-mix(in oklch, #2563eb, white) ?light-dark() et quand l'utiliser ?rgba() ?currentColor et inherit ?rgb() utilise rouge-vert-bleu (additif), hsl() utilise teinte-saturation-luminosité (plus intuitif pour varier).oklch() est perceptuellement uniforme : une luminosité de 0.6 a la même intensité perçue quelle que soit la teinte.color-scheme: light dark; sur :root.light-dark(clair, sombre) retourne la bonne couleur selon le mode actif. Plus concis qu'une media query.oklch(), light-dark(), etc. — sans fallback, la propriété est ignorée.rgb(37 99 235 / 0.5) — espaces entre canaux, / pour l'alpha.currentColor = la valeur computed de color de l'élément. inherit = la valeur héritée du parent (peut être différente si une règle s'applique).┌─────────────────────────────────────────────────────────────────────┐ │ CHEAT SHEET — COULEURS CSS │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ FORMATS : │ │ ──────── │ │ red, blue, tomato nommées (148 au total) │ │ #ff0000 #f00 HEX (6 ou 3 chiffres + alpha optionnel) │ │ rgb(r g b / a) rouge-vert-bleu (0-255 ou %) │ │ hsl(h s% l% / a) teinte-saturation-luminosité │ │ hwb(h w% b%) teindle-blanc-noir │ │ oklch(l c h / a) perceptuellement uniforme (recommandé) │ │ │ │ FONCTIONS : │ │ ────────── │ │ color-mix(in espace, c1 %, c2 %) mélanger des couleurs │ │ light-dark(couleur-claire, sombre) adaptatif (auto dark mode) │ │ currentColor valeur de color de l'élément │ │ transparent rgba(0 0 0 / 0) │ │ color(display-p3 ...) gamut plus large (P3) │ │ │ │ ACCESSIBILITÉ : │ │ ─────────────── │ │ WCAG AA : ratio 4.5:1 (texte normal) / 3:1 (texte grand) │ │ WCAG AAA : ratio 7:1 (texte normal) / 4.5:1 (texte grand) │ │ │ │ DARK MODE : │ │ ────────── │ │ color-scheme: light dark; déclarer le support │ │ @media (prefers-color-scheme: dark) media query classique │ │ light-dark(a, b) fonction moderne (recommandée) │ │ │ │ SYSTÈME DE COULEURS : │ │ ───────────────────── │ │ Niveau 1 : Primitives (valeurs brutes en oklch) │ │ Niveau 2 : Sémantiques (--bg-primary, --text-secondary) │ │ Niveau 3 : Composants (--btn-bg, --card-border) │ │ │ │ BONNES PRATIQUES : │ │ ───────────────── │ │ 1. oklch() pour les palettes │ │ 2. color-mix() pour les variantes │ │ 3. light-dark() pour le dark mode │ │ 4. Toujours un fallback pour les couleurs modernes │ │ 5. Vérifier le contraste WCAG AA │ │ 6. Variables pour toutes les couleurs utilisées │ │ 7. 3 niveaux : primitives → sémantique → composant │ └─────────────────────────────────────────────────────────────────────┘
Résumé complet de toutes les notions sur les couleurs CSS