Retour au cours

frontend / css

Accessibilité visuelle : contraste et mouvement

Leçon 171 exercice

Explication

Ce que vous allez apprendre

  • Vérifier qu'un contraste texte/fond respecte les seuils mesurables de la norme WCAG
  • Éviter de coder une information uniquement par la couleur (accessibilité pour les daltoniens)
  • Respecter la préférence système "réduire les animations" avec prefers-reduced-motion
  • Adapter un design au mode contraste élevé avec prefers-contrast et forced-colors
  • Dimensionner correctement les cibles tactiles (boutons, liens) pour rester utilisables

Dans quel contexte ?

Une administration publique refait le design de son site de démarches en ligne. Un audit d'accessibilité révèle que le gris clair utilisé pour les textes secondaires (#aaaaaa sur fond blanc) est illisible pour une partie des usagers malvoyants, et que les messages d'erreur, uniquement rouges, restent invisibles pour les daltoniens. Cette leçon couvre exactement les correctifs CSS à apporter dans ce type de situation.

Étape 1 : un enjeu d'accessibilité qu'on oublie

On pense rarement au CSS comme un enjeu d'accessibilité — on associe plutôt ce sujet au HTML sémantique ou à ARIA. Pourtant, un mauvais choix de couleur ou une animation trop intense peut rendre un site inutilisable pour une part importante des visiteurs.

Étape 2 : le contraste, une exigence mesurable

Commençons par le contraste. La différence de luminosité entre un texte et son fond détermine littéralement si le texte reste lisible pour une personne malvoyante, ou pour n'importe qui en plein soleil sur un smartphone.

Étape 3 : des seuils précis, pas une opinion

La norme WCAG fixe des seuils mesurables, comme 4.5:1 pour du texte normal — un gris clair "joli" mais insuffisamment contrasté échoue objectivement ce critère, quel que soit l'avis du designer.

Type de contenuRatio minimum (AA)
Texte normal4.5:1
Texte large (≥ 24px, ou ≥ 19px gras)3:1
Éléments d'interface (icônes, bordures)3:1

Étape 4 : ne jamais reposer sur la seule couleur

Une autre erreur très répandue consiste à indiquer un état (erreur, succès) uniquement par une couleur différente. Pour une personne daltonienne, cette distinction peut être totalement invisible.

Étape 5 : la bonne pratique à adopter

Il faut toujours doubler l'information colorée d'un second indicateur — une icône, un texte, une forme — pour que le sens reste accessible indépendamment de la perception des couleurs.

Piège fréquent

Un message d'erreur affiché uniquement en rouge (color: red;) sans icône ni texte explicite est invisible pour près de 8% des hommes daltoniens. Ajoutez toujours un indicateur non-couleur : le mot "Erreur" affiché en préfixe, ou une bordure en pointillés.

Étape 6 : respecter la préférence "réduire les animations"

Il reste un dernier point : certaines personnes ressentent un véritable inconfort physique face à des animations trop marquées. prefers-reduced-motion: reduce détecte cette préférence système.

Et ensuite ?

Le CSS doit alors désactiver ou atténuer les animations non essentielles, en gardant celles qui transmettent une information utile. Une fois l'accessibilité visuelle comprise, la prochaine étape s'attaque à la performance de rendu du navigateur.

Commandes & code

Accessibilité visuelle : contraste et mouvement

Le CSS influence directement qui peut lire et utiliser confortablement une interface.

css
/* Contraste : la norme WCAG AA exige un ratio minimum
   - 4.5:1 pour le texte normal
   - 3:1 pour le texte large (>= 24px, ou >= 19px en gras) */

:root {
    --texte-sur-fond-clair: #1a1a1a;  /* sur #ffffff -> ratio ~19:1, largement conforme */
    --gris-insuffisant: #aaaaaa;      /* sur #ffffff -> ratio ~2.3:1, ÉCHOUE en AA */
    --gris-conforme: #595959;         /* sur #ffffff -> ratio ~7:1, conforme AAA */
}

/* Ne JAMAIS coder l'information UNIQUEMENT par la couleur */
.statut-erreur {
    color: #dc2626;
    /* + un indicateur non-couleur : icône, texte, forme */
}
.statut-erreur::before {
    content: "Erreur : ";
}
css
/* prefers-reduced-motion : respecter le choix système de l'utilisateur */
.carte {
    transition: transform 0.3s ease;
}
.carte:hover {
    transform: translateY(-4px);
}

@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
/* approche alternative, plus fine : désactiver seulement les animations
   non essentielles (garder par ex. un spinner de chargement) */
.decoration-uniquement {
    animation: pulsation 2s infinite;
}
@media (prefers-reduced-motion: reduce) {
    .decoration-uniquement { animation: none; }
}
css
/* prefers-contrast : renforcer le contraste pour les utilisateurs qui le demandent */
@media (prefers-contrast: more) {
    :root {
        --bordure: #000000;
        --texte: #000000;
    }
    .bouton {
        border: 2px solid currentColor; /* bordure visible même sans couleur de fond différenciée */
    }
}

/* forced-colors : compatibilité avec le mode "High Contrast" de Windows */
@media (forced-colors: active) {
    .badge {
        forced-color-adjust: none; /* garde un style custom quand c'est vraiment nécessaire */
        border: 1px solid CanvasText; /* couleurs système, garantissent le contraste */
    }
}
css
/* Taille de cible tactile : WCAG recommande 44x44px minimum */
.bouton-icone {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Zoom texte : ne jamais bloquer le zoom utilisateur */
/* MAUVAIS */
/* <meta name="viewport" content="width=device-width, user-scalable=no"> */
/* Autoriser systématiquement le zoom (retirer user-scalable=no, maximum-scale) */

Résumé

  • Un contraste de 4.5:1 minimum (texte normal) est la référence WCAG AA, pas une suggestion esthétique.
  • L'information ne doit jamais reposer sur la seule couleur (icône, texte ou forme en complément).
  • prefers-reduced-motion: reduce doit désactiver ou réduire les animations non essentielles.
  • Les cibles tactiles (boutons, liens) visent un minimum de 44x44px pour rester utilisables.

Exercices pratiques

1 disponible
1

Mission : un audit d'accessibilité qui recale un site public

Objectif : Corriger un contraste insuffisant, une information codée uniquement par la couleur, et une animation ignorant les préférences système.

Contexte

L'audit du site de démarches en ligne relève trois problèmes sur demarche.css : le texte d'aide secondaire utilise color: #aaaaaa; sur fond blanc, le message de succès d'un formulaire n'est signalé que par color: green; sans aucun autre indice visuel, et une carte anime transform: translateY(-4px) au survol via transition: transform 0.3s ease; sans tenir compte d'aucune préférence système.

Résoudre l’exercice →