Chapitre 18 : Accessibilité des contrastes et Media Query prefers-contrast
Adaptation des interfaces aux préférences utilisateur pour un contraste élevé
L'accessibilité numérique ne se limite pas à l'ajout d'attributs alt sur les images ou à la gestion du focus clavier. L'une des dimensions les plus critiques est la perception visuelle. Pour de nombreux utilisateurs, notamment les personnes malvoyantes ou souffrant de daltonisme, le contraste standard d'un site web peut être insuffisant pour distinguer le texte du fond ou identifier les éléments interactifs.
Le CSS moderne propose un outil puissant pour répondre à ce besoin : la media query prefers-contrast.
Le Contraste et l'Accessibilité Visuelle
1. Quoi
Le contraste est la différence de luminance ou de couleur entre le premier plan (le texte, l'icône) et l'arrière-plan. En accessibilité, on parle souvent de ratio de contraste.
La media query prefers-contrast est une requête de préférence utilisateur. Elle permet au navigateur de savoir si l'utilisateur a activé une option de "Contraste élevé" dans les paramètres de son système d'exploitation (Windows, macOS, iOS, Android).
Elle accepte trois valeurs principales :
no-preference: L'utilisateur n'a pas exprimé de préférence particulière.more: L'utilisateur souhaite un contraste plus élevé que la normale.custom: L'utilisateur a défini des couleurs de contraste spécifiques dans son système (très courant sur Windows High Contrast Mode).
2. Pourquoi
Dans un projet professionnel, ignorer le contraste peut rendre votre application totalement inutilisable pour une partie de votre audience.
L'utilité réelle se manifeste dans plusieurs scénarios :
- Malvoyance : Certaines personnes ne perçoivent pas les nuances de gris clair sur fond blanc.
- Environnements lumineux : Un utilisateur travaillant en plein soleil peut activer le mode contraste élevé pour mieux lire.
- Conformité légale : Le respect des normes WCAG (Web Content Accessibility Guidelines) impose des ratios de contraste minimums (4.5:1 pour le texte normal, 3:1 pour le texte large).
L'utilisation de prefers-contrast permet de ne pas imposer un design "austère" à tout le monde, mais de proposer une version optimisée uniquement à ceux qui en ont réellement besoin.
3. Comment
A. Syntaxe de base
La syntaxe est identique à celle d'une media query classique comme @media (max-width: 600px).
/* Styles pour les utilisateurs demandant un contraste élevé */
@media (prefers-contrast: more) {
body {
background-color: black;
color: white;
}
}
B. Cas concret : Interface Professionnelle
Dans un projet réel, on ne change pas brutalement toutes les couleurs. On utilise des variables CSS (Custom Properties) pour basculer intelligemment les teintes.
:root {
/* Palette standard : douce et moderne */
--bg-color: #f8f9fa;
--text-color: #495057;
--accent-color: #007bff;
--border-color: #dee2e6;
}
/* Adaptation pour contraste élevé */
@media (prefers-contrast: more) {
:root {
/* Palette contrastée : noir pur, blanc pur, couleurs saturées */
--bg-color: #ffffff;
--text-color: #000000;
--accent-color: #0000ff; /* Bleu plus profond et saturé */
--border-color: #000000;
}
}
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: sans-serif;
line-height: 1.6;
}
.card {
border: 2px solid var(--border-color);
padding: 1rem;
margin: 1rem 0;
}
.btn-primary {
background-color: var(--accent-color);
color: white;
border: 2px solid var(--border-color);
padding: 0.5rem 1rem;
cursor: pointer;
font-weight: bold;
}
C. Limitations
- Support Navigateur : Bien que largement supporté, certains anciens navigateurs ignorent cette requête. Il faut toujours concevoir un design "de base" qui est déjà raisonnablement accessible.
- Le mode "Custom" : La valeur
customest particulière. Sur Windows, le mode "Contraste Élevé" peut forcer certaines couleurs et ignorer vos propriétésbackground-color. Dans ce cas, il est préférable d'utiliser des bordures (border) pour délimiter les éléments, car elles sont mieux préservées. - Dépendance OS : Le développeur ne peut pas "forcer" ce mode via CSS ; c'est l'utilisateur qui doit l'activer dans ses réglages système.
4. Zone de Danger
❌ L'erreur commune : Utiliser uniquement la couleur pour transmettre une information.
Exemple : Un champ de formulaire qui devient rouge quand il y a une erreur, sans ajouter d'icône ou de texte. Même avec prefers-contrast: more, un utilisateur daltonien pourrait ne pas voir la différence.
✅ La bonne pratique : Combiner le contraste élevé avec des indicateurs visuels redondants. Exemple : Ajouter une bordure épaisse et une icône d'alerte en plus du changement de couleur.
Flux de détection du contraste utilisateur
Questions clés
1. Quelle est la différence entre prefers-color-scheme et prefers-contrast ?
Découvrir la réponse
prefers-color-scheme gère le mode clair ou sombre (esthétique et confort visuel), tandis que prefers-contrast gère la lisibilité et la distinction des éléments (accessibilité pure). Un utilisateur peut vouloir le mode sombre (dark) MAIS sans contraste élevé, ou inversement.
2. Pourquoi utiliser des variables CSS avec prefers-contrast ?
Découvrir la réponse
L'utilisation de variables permet de maintenir un code propre. Au lieu de réécrire toutes les règles CSS dans la media query, on ne modifie que la valeur des variables au sommet du document (:root), et tout le reste du site se met à jour automatiquement.
3. Que se passe-t-il si l'utilisateur n'a pas configuré de préférence de contraste ?
Découvrir la réponse
Le navigateur renvoie no-preference. Dans ce cas, les styles à l'intérieur de @media (prefers-contrast: more) sont simplement ignorés, et le site affiche ses styles par défaut.
4. Comment tester prefers-contrast sans changer les réglages de mon ordinateur ?
Découvrir la réponse
Dans les outils de développement de Chrome ou Firefox (Inspecteur), vous pouvez simuler les préférences utilisateur. Dans Chrome : Inspecteur → Trois points → More tools → Rendering → Emulate CSS media feature prefers-contrast.
Mise en pratique
Exercice 1 : Reproduction guidée (Niveau Junior)
Objectif : Créer un bouton simple qui change d'apparence lorsque le mode contraste élevé est activé.
- Créez un bouton avec un fond gris clair et un texte gris foncé.
- Utilisez
prefers-contrast: morepour transformer ce bouton en fond noir avec texte blanc et une bordure blanche de 3px.
Découvrir la solution commentée
/* Style standard : faible contraste */
.btn-test {
background-color: #e0e0e0;
color: #666666;
padding: 10px 20px;
border: 1px solid #ccc;
cursor: pointer;
}
/* Adaptation pour accessibilité */
@media (prefers-contrast: more) {
.btn-test {
background-color: #000000; /* Noir pur pour max contraste */
color: #ffffff; /* Blanc pur */
border: 3px solid #ffffff; /* Bordure renforcée pour visibilité */
font-weight: bold; /* Améliore la lisibilité */
}
}
Exercice 2 : Adaptation (Niveau Junior)
Objectif : Adapter une barre de navigation.
HTML de départ :
<nav class="nav">
<a href="#">Accueil</a>
<a href="#">Services</a>
<a href="#">Contact</a>
</nav>
CSS de départ (à adapter) :
.nav {
background-color: #eef2ff;
padding: 1rem;
}
.nav a {
color: #4f46e5;
text-decoration: none;
margin-right: 15px;
}
Ajoutez un bloc @media (prefers-contrast: more) pour que, en mode contraste élevé, le fond devienne blanc et les liens deviennent d'un bleu foncé très saturé (#00008b) avec un soulignement permanent.
Découvrir la solution commentée
.nav {
background-color: #eef2ff;
padding: 1rem;
}
.nav a {
color: #4f46e5;
text-decoration: none;
margin-right: 15px;
}
@media (prefers-contrast: more) {
.nav {
background-color: #ffffff; /* Fond neutre et clair */
}
.nav a {
color: #00008b; /* Bleu foncé pour ratio élevé */
text-decoration: underline; /* Indicateur visuel supplémentaire */
font-weight: 700;
}
}
Exercice 3 : Conception (Niveau Junior)
Objectif : Créer un système de "Cartes d'information" accessibles.
HTML de départ :
<div class="dashboard">
<div class="card">
<h3>Revenus</h3>
<p>12 450 €</p>
<span class="card-help">Mis à jour il y a 2h</span>
</div>
<div class="card">
<h3>Commandes</h3>
<p>348</p>
<span class="card-help">Ce mois-ci</span>
</div>
</div>
Chaque carte a une ombre portée (box-shadow) pour se détacher du fond, mais pas de bordure.
- Problème : Les ombres sont souvent invisibles pour les personnes ayant besoin d'un contraste élevé.
- Mission : Concevez le CSS pour que, en mode
prefers-contrast: more, l'ombre disparaisse au profit d'une bordure noire épaisse et que le texte d'aide (actuellement en gris clair) devienne noir intense.
Découvrir la solution commentée
:root {
--card-bg: #ffffff;
--card-shadow: 0 4px 6px rgba(0,0,0,0.1);
--help-text: #888888;
--border-style: none;
}
@media (prefers-contrast: more) {
:root {
--card-shadow: none; /* Les ombres sont inutiles en contraste élevé */
--help-text: #000000; /* Texte d'aide rendu parfaitement lisible */
--border-style: 3px solid #000000; /* Remplacement de l'ombre par une ligne nette */
}
}
.card {
background-color: var(--card-bg);
box-shadow: var(--card-shadow);
border: var(--border-style);
padding: 20px;
border-radius: 8px;
}
.card-help {
color: var(--help-text);
font-size: 0.85rem;
}