RGAA Lab

Composants accessibles

Les gestes et le mouvement

Un geste n'est jamais la fonctionnalité : c'est un raccourci posé par-dessus des commandes que tout le monde peut atteindre. Pincement, balayage, secousse, orientation — ce que le RGAA exige, et une démo qui le montre.

5 critères RGAA en jeu

Essayez-le

Scène

A 1 à 12 — accès de plain-pied

B 1 à 14

C 1 à 14 — deux places réservées

D 1 à 16

Agrandissement : 100 %

Dernier agrandissement obtenu par : rien pour l'instant

Dernier appui sur un bouton : rien pour l'instant

Orientation de l'écran : relevé au chargement — la démo est la même dans l'autre.

Agrandissez le plan au clavier seul : le relevé indique « le clavier », parce qu’il lit ce qui s’est passé plutôt que de l’annoncer d’avance. Sur un écran tactile, pincez à deux doigts : le même agrandissement arrive par un autre chemin. Enfin, posez le pointeur sur « Agrandir », faites-le glisser en dehors du bouton, puis relâchez — rien ne se produit, et le relevé le dit.

Cette démo existe aussi en page autonome.

L’erreur courante

Le carrousel qui ne se parcourt qu’au balayage. Le composant écoute la trajectoire du doigt, et rien d’autre.

<!-- À ne pas faire : le geste est la seule commande -->
<div class="carrousel" ontouchstart="debutBalayage(event)" ontouchend="finBalayage(event)">
	<figure></figure>
</div>

Ce qui est perdu tient en une phrase : la fonctionnalité n’existe que pour qui peut tracer. Au clavier, aucune touche ne fait avancer le carrousel. À la commande vocale, il n’y a rien à nommer. Au contacteur ou au joystick, un pointeur se déplace et clique, mais ne trace pas. Et une personne qui tient son téléphone d’une main tremblante balaye deux vues au lieu d’une.

Le second cas est plus visible encore, et souvent assumé :

/* À ne pas faire : le service s'interrompt dans une orientation */
@media (orientation: landscape) {
	.application { display: none; }
	.tournez-votre-appareil { display: block; }
}

Une tablette fixée sur un bras articulé ou sur un fauteuil roulant ne tourne pas. Le message n’est pas une gêne, c’est une porte fermée.

Trois variantes rencontrées souvent :

  • Le zoom d’une carte au seul pincement. Sans « + » et « − », le détail de la carte est réservé à qui peut écarter deux doigts.
  • « Glisser pour supprimer » dans une liste, sans bouton de suppression. L’action existe, mais personne ne peut la trouver ni la déclencher autrement.
  • « Secouez pour signaler un problème », sans commande équivalente ni moyen de couper le capteur : la fonction part toute seule chez qui tremble.

Le code, pas à pas

1. Écrire la commande d’abord, le geste ensuite

C’est l’ordre qui décide de tout le reste. Une commande — un <button>, un lien, une entrée de menu — porte la fonctionnalité ; le geste vient par-dessus, comme un raccourci pour qui peut le faire.

<button type="button" onclick="agrandir()">Agrandir</button>
<button type="button" onclick="reduire()">Réduire</button>

Écrit dans l’autre sens — le geste d’abord, le bouton « quand on aura le temps » — le bouton n’arrive jamais, ou arrive en doublant mal : il fait presque la même chose, et c’est ce presque qui fait échouer le critère 13.10, qui demande un résultat identique.

2. Le pincement : plusieurs doigts, un seul point

Un geste à deux doigts est un contact multipoint. Le référentiel demande que la fonctionnalité soit aussi disponible par un contact en un point unique de l’écran.

// Deux pointeurs suivis, et l'écart entre eux qui règle l'agrandissement
cadre.addEventListener('pointerdown', (evenement) => {
	pointeurs.set(evenement.pointerId, { x: evenement.clientX, y: evenement.clientY });
	if (pointeurs.size === 2) ecartInitial = ecartCourant();
});

Le geste peut rester : le critère demande une alternative, pas une suppression. Ce qui doit rester vrai, c’est que le pincement et le bouton passent par la même fonction — deux chemins vers un seul endroit, sinon ils divergent au premier correctif.

Côté CSS, la déclaration touch-action décide de ce que le navigateur garde pour lui :

.cadre {
	/* Le défilement à un doigt reste au navigateur, le geste à deux doigts nous revient */
	touch-action: pan-x pan-y;
}

Limitez-la à la zone concernée. Posée sur toute la page, elle retirerait le zoom tactile du navigateur, c’est-à-dire un moyen d’agrandissement dont beaucoup de gens dépendent.

3. Le balayage : une trajectoire, deux boutons

Le second test du critère 13.10 vise le geste basé sur le suivi d’une trajectoire : balayer, glisser, tracer. La réponse est la même, et elle est banale — des boutons « Précédent » et « Suivant », atteignables et nommés.

Ils ne se cachent pas au survol : un bouton qui n’apparaît qu’au passage de la souris n’existe ni au doigt, ni au clavier avant qu’il soit trop tard.

4. L’action part au relâchement

Un geste s’interrompt : c’est ce qui le rend rattrapable. Le critère 13.11 accepte trois montages, dont le plus simple est le comportement par défaut de click.

// L'action part au relâchement, et le relâchement hors de la cible ne la déclenche pas
bouton.addEventListener('click', agrandir);

// À ne pas faire : l'action est partie dès que le doigt s'est posé
bouton.addEventListener('pointerdown', agrandir);

pointerdown gagne quelques dizaines de millisecondes de réactivité et perd le droit à l’erreur. Sur une action destructrice — supprimer, envoyer, payer — c’est un mauvais échange.

5. Le mouvement de l’appareil : un bouton et un interrupteur

Le critère 13.12 porte trois tests, et le troisième surprend : offrir une commande équivalente ne dispense pas de pouvoir couper la détection.

<button type="button" onclick="reinitialiser()">Réinitialiser</button>

<input type="checkbox" id="secousse" checked />
<label for="secousse">Réinitialiser en secouant l'appareil</label>

Les deux obligations visent deux personnes différentes. Le bouton sert à qui ne peut pas bouger son appareil ; l’interrupteur sert à qui le bouge sans le vouloir, et qui déclenche la fonction dix fois par heure.

6. Les deux orientations

Le critère 13.9 demande que le contenu reste consultable en portrait comme en paysage. La présentation peut changer, et le chemin pour atteindre une information aussi ; le contenu, non.

En pratique : ne verrouillez pas l’orientation, n’affichez pas de message demandant de tourner l’appareil, et vérifiez qu’aucune partie de la page ne devient inatteignable dans l’une des deux — un pied de page hors d’atteinte en paysage échoue autant qu’un blocage explicite.

WCAG réserve le cas où une orientation est essentielle : un piano virtuel, un chèque à photographier. Une mise en page qu’on n’a pas eu le temps d’adapter n’entre pas dans cette catégorie.

7. Ce geste, en avez-vous besoin ?

Un geste sans commande équivalente est une fonctionnalité inaccessible ; un geste avec commande équivalente est une deuxième implémentation à maintenir, à tester et à corriger deux fois. Il se justifie quand il rend un usage courant plus rapide — feuilleter, zoomer sur une carte. Rarement ailleurs.

Au clavier

ToucheEffet
TabPasse sur « Réduire », « Agrandir », « Réinitialiser », puis sur le cadre du plan, qui défile.
Entrée / EspaceActive le bouton qui a le focus ; le focus ne bouge pas, même aux bornes de l’agrandissement.
Font défiler le plan agrandi quand le focus est dans le cadre.
AucuneLe pincement n’a pas d’équivalent clavier, et n’en cherche pas : ce sont les boutons qui portent la fonction.

Ce que le lecteur d’écran restitue

Sur une commande : le nom et la nature — « Agrandir, bouton ». Après activation, la région de statut annonce le résultat : « Agrandissement 150 % ». Sur le réglage du capteur : « Réinitialiser en secouant l’appareil, case à cocher, non cochée ». La formulation varie d’un lecteur à l’autre, pas les informations.

Si vous n’entendez rien après avoir agrandi, aucune région de statut ne relaie le changement : le geste et son résultat ne s’adressent qu’à l’œil. Si la tabulation ne rencontre aucune commande, la fonctionnalité n’existe qu’au geste — et le critère 13.10 échoue avant même qu’on parle de lecteur d’écran.

Checklist

  • Écrire la commande d’abord ; le geste vient par-dessus, jamais à sa place.
  • Doubler chaque geste à plusieurs doigts ou à trajectoire par un contact en un point unique, qui produit le même résultat.
  • Faire partir l’action au relâchement (click), pas au contact (pointerdown).
  • Doubler le mouvement de l’appareil d’une commande et offrir de couper le capteur.
  • Ne verrouiller aucune orientation, ne demander à personne de tourner son appareil.
  • Annoncer le résultat du geste dans une région de statut : un geste ne s’entend pas.
  • Limiter touch-action à la zone du geste, jamais à la page.

Les critères RGAA en jeu

Vérifiez votre composant avec l'extension

Pour aller plus loin

Sources