Les fenêtres surgissantes et les flashs
Deux exigences qui protègent de ce qu'on n'a pas demandé : la fenêtre qui s'ouvre seule, et le flash qui peut déclencher une crise. Démo chronométrée, code, critères RGAA.
2 critères RGAA en jeu
Essayez-le
Mesuré dans la page : 0 flash sur la dernière seconde, zone de 0 pixels.
Fréquence : 2 par seconde, inférieure à 3.
Surface : 0 pixels, au-dessus du seuil de 21 824.
Lancez l’effet à une puis deux fois par seconde, et regardez le compteur : il relève le rythme réel du minuteur sur la dernière seconde, pas la valeur choisie. Passez à huit par seconde — la zone cesse aussitôt de s’allumer, parce qu’un seuil est un danger et non une illustration, mais le compte continue et le verdict bascule. Puis réduisez la zone sans toucher au rythme : la surface, relue dans le rendu et non dans la feuille de styles, passe sous 21 824 pixels et le réglage redevient conforme, parce que les deux conditions du test sont des alternatives.
Cette démo existe aussi en page autonome.
L’erreur courante
La fenêtre qui s’ouvre parce que la page a fini de charger.
<script>
// À ne pas faire : personne n'a demandé cette fenêtre
window.addEventListener('load', () => {
window.open('/offre', 'offre', 'width=480,height=360');
});
</script> Ce que ça coûte : le focus quitte la page, et le lecteur d’écran se met à lire un autre document sans que rien n’explique pourquoi. Qui utilise un agrandisseur perd son repère : la loupe suit le focus, et le focus vient de changer de fenêtre. Le bouton Retour du navigateur ne ramène pas en arrière — il n’y a pas d’arrière, il y a une autre fenêtre à refermer, à la souris ou par le gestionnaire de fenêtres du système.
S’y ajoute un effet pervers pour l’équipe qui code : les bloqueurs de fenêtres avalent souvent l’ouverture avant qu’on l’ait vue. Le défaut existe, et personne dans l’équipe ne le rencontre.
Trois variantes, exactement aussi fautives parce qu’aucune ne part d’une action :
- L’ouverture différée — un
setTimeoutde quinze secondes. Le délai ne transforme pas l’absence d’action en action. - L’ouverture à la sortie du curseur — le pointeur monte vers la barre d’adresse, une fenêtre s’ouvre. Bouger une souris n’est pas demander une fenêtre, et l’utilisateur au clavier ne déclenche jamais rien.
- L’ouverture à la prise de focus —
onfocus="window.open(…)"sur un champ. C’est le pire des trois : la tabulation suffit à l’armer, donc naviguer au clavier devient impossible.
Et du côté du flash, l’erreur tient en trois lignes de CSS :
/* À ne pas faire : environ huit flashs par seconde, sur toute la bannière */
@keyframes alerte {
50% { background: #fff; }
}
.banniere { animation: alerte 0.12s infinite; } Personne n’a écrit « huit flashs par seconde » : on a écrit 0.12s, ce qui n’a
pas l’air d’un nombre dangereux. C’est ce qui rend ce défaut si fréquent — il ne
se voit pas dans le code, il se calcule.
Ce qui n’est pas visé par le 13.2
Un lien que l’on clique, même avec target="_blank", ne relève pas de ce
critère : cliquer est une action de l’utilisateur. Le 13.2 vise l’ouverture
« sans action de l’utilisateur », et rien d’autre.
Annoncer la nouvelle fenêtre dans l’intitulé du lien reste une bonne pratique — le changement de contexte surprend — mais ce n’est pas ce critère qui l’exige. Le sujet est traité dans la fiche des liens.
Le code, pas à pas
1. Une fenêtre s’ouvre après une action, ou ne s’ouvre pas
<button type="button" id="ouvrir-simulateur">
Ouvrir le simulateur dans une nouvelle fenêtre
</button> document.querySelector('#ouvrir-simulateur').addEventListener('click', () => {
window.open('/simulateur', 'simulateur');
}); Le clic est l’action, l’intitulé prévient, et le bloqueur du navigateur laisse
passer — les navigateurs autorisent window.open appelé depuis un geste
utilisateur, et le bloquent sinon. La règle du navigateur et celle du
référentiel se recouvrent presque : si le bloqueur intervient, vous étiez
probablement déjà en dehors du 13.2.
2. Une modale n’est pas une fenêtre
Le bandeau de consentement ou la modale d’inscription qui s’ouvre au chargement n’est pas une nouvelle fenêtre : c’est du contenu de la page, et le 13.2 ne le vise pas. Écrire l’inverse dans un rapport d’audit est une non-conformité inventée.
Ce qui reste vrai, en revanche, c’est le contrat de la modale elle-même : le focus conduit dedans puis rendu, la fermeture au clavier, le reste de la page rendu inerte. C’est le sujet de la fiche modale, et c’est là que se juge une modale qui s’impose au chargement.
3. Compter les flashs avant de les écrire
Le test 13.7 pose deux conditions, et il en suffit d’une :
- la fréquence de l’effet est inférieure à 3 par seconde ;
- la surface totale cumulée des effets est inférieure ou égale à 21 824 pixels.
Reste à traduire une animation en fréquence. Un flash est un cycle complet —
la zone s’allume, la zone s’éteint. Une animation dont la durée de cycle est 0.12s produit donc environ 8,3 flashs par seconde ; à 0.5s, deux ; à 0.33s, un peu plus de trois — ce qui échoue déjà, puisque le seuil est inférieur à trois et non au plus trois.
/* Une durée de cycle d'au moins 0,34 s tient la première condition */
.pastille { animation: pulsation 0.5s infinite; } Le calcul vaut pour tout ce qui produit l’effet, et le référentiel énumère les
trois sources séparément : les images et médias (test 13.7.1), les scripts
(13.7.2), les mises en forme CSS (13.7.3). Une vidéo de trois secondes de
stroboscope compte autant qu’un @keyframes.
4. La surface, quand la fréquence ne peut pas baisser
21 824 pixels, c’est un carré d’à peu près 148 pixels de côté. Le mot qui compte est cumulée : six pastilles de 60 × 60 qui clignotent ensemble font 21 600 pixels et tiennent tout juste, une septième fait échouer le test. Et la surface se mesure sur le rendu, pas sur la feuille de styles — une zone en pourcentage change de surface avec la fenêtre, ce que la démo ci-dessus donne à voir.
Une précision qui ne vient pas du référentiel mais de la ressource WCAG dont il dérive : les flashs rouges saturés sont traités à part, parce qu’ils déclenchent à des seuils plus bas. En cas de doute sur un contenu vidéo, un analyseur de photosensibilité tranche mieux que l’œil, qui ne sait pas compter jusqu’à trois en une seconde.
5. prefers-reduced-motion : une bonne pratique, pas une obligation
@media (prefers-reduced-motion: reduce) {
.pastille { animation: none; }
} Le référentiel ne l’exige nulle part. Aucun critère du RGAA ne mentionne cette préférence, et la respecter ne rend conforme aucun des deux critères de cette fiche.
Elle ne protège d’ailleurs pas de la même chose. Elle retire l’effet à qui l’a réglée dans son système — c’est-à-dire à une minorité avertie. Le 13.7, lui, protège tout le monde, y compris la personne qui découvre sa photosensibilité sur votre page. Un flash au-dessus du seuil reste un danger pour qui n’a rien réglé : la préférence n’est pas une défense.
Cela dit, la respecter est juste, et coûte trois lignes. La démo de cette fiche le fait : si votre système demande moins d’animations, la zone ne s’allume pas et le compteur continue de tourner.
6. Avez-vous besoin de cette fenêtre ?
C’est la question la plus rentable de la fiche. Une fenêtre surgissante existe presque toujours pour montrer quelque chose que la page pouvait contenir : une offre, un avertissement, un formulaire court. Le rendre dans le flux ne coûte rien à personne, se retrouve par la recherche du navigateur, s’imprime, se partage par une URL, et ne pose aucune question d’accessibilité.
Au clavier
| Touche | Effet |
|---|---|
| Tab | Entre dans le groupe de fréquences (un seul arrêt), puis va aux deux boutons. Rien ne s’ouvre à la prise de focus — c’est le défaut que le 13.2 vise. |
| ← → | Change de fréquence dans le groupe de boutons radio, et le verdict suit. |
| Espace / Entrée | Lance ou arrête l’effet, réduit ou agrandit la zone, selon le bouton qui a le focus. |
| Hors de la page | Revenir d’une fenêtre ouverte sans action passe par le gestionnaire de fenêtres du système. Le bouton Retour du navigateur n’y peut rien : la page d’origine n’a pas bougé. |
Ce que le lecteur d’écran restitue
Sur le groupe de fréquences : « Fréquence de l’effet, 2 par seconde, bouton radio sélectionné, 2 sur 4 ». Sur la bascule : « Lancer l’effet, bouton », puis « Arrêter l’effet, bouton » — c’est le nom qui change, et il dit l’état suivant.
Avant le premier geste, la région de statut est là mais vide : rien n’est annoncé tant que rien n’a été demandé. Après chaque changement, elle annonce le verdict, et lui seul : « Effet en cours. Le réglage ne vérifie aucune des deux conditions du test 13.7. » La formulation varie d’un lecteur à l’autre, pas les informations.
Si vous n’entendez rien après avoir lancé l’effet, la région de statut a été créée au moment de l’annonce au lieu d’exister, vide, dès le premier rendu. Si vous entendez relire le bilan entier pendant que vous redimensionnez la fenêtre, c’est que des nombres mesurés ont été placés dans la région de statut : ils n’ont rien à y faire.
Et pour le 13.2, le diagnostic est plus simple encore : si le lecteur d’écran se met à annoncer un autre titre de page sans que vous ayez activé quoi que ce soit, vous venez de constater le défaut.
Checklist
- Rien ne s’ouvre au chargement, après une temporisation, au survol ni à la prise de focus.
- Une nouvelle fenêtre ne s’ouvre qu’à la suite d’un clic ou d’une activation clavier.
- Un lien avec
target="_blank"ne relève pas du 13.2 ; l’annoncer reste une bonne pratique. - Compter les flashs : moins de trois par seconde, ou surface cumulée d’au plus 21 824 pixels.
- Traduire chaque
animation-durationen flashs par seconde, plutôt que s’en remettre à l’œil. - Se méfier des flashs rouges saturés, que les WCAG traitent à seuil plus bas.
- Respecter
prefers-reduced-motionsans le prendre pour une conformité.
Les critères RGAA en jeu
- Critère 13.2 — Ouverture de nouvelle fenêtre
Une fenêtre ouverte au chargement, après une temporisation ou à la prise de focus déplace le contexte sans que personne l'ait demandé — c'est précisément ce que le critère interdit, et un lien que l'on clique n'en relève pas.
- Critère 13.7 — Effets de flash et luminosité
Au-delà de trois flashs par seconde sur une surface suffisante, l'effet peut déclencher une crise d'épilepsie photosensible : le défaut ne gêne pas, il blesse, et l'œil ne sait pas compter jusqu'à trois en une seconde.
Vérifiez votre composant avec l'extension
Pour aller plus loin
- Critère 13.2 — Ouverture de nouvelle fenêtre et 13.7 — Effets de flash et luminosité : les deux textes, et la méthode de contrôle de chacun.
- Le carrousel : le voisin immédiat, avec le critère 13.8, qui borne cette fois le mouvement plutôt que le flash.
- La modale : ce qui se juge vraiment sur une fenêtre d’inscription au chargement, puisque le 13.2 ne la vise pas.
- Les liens :
target="_blank", et pourquoi l’annonce de la nouvelle fenêtre est une bonne pratique et non une exigence. - « Changement brusque de luminosité ou effet de flash » au glossaire : la définition officielle à laquelle le test 13.7 renvoie.
Sources
- MDN —
prefers-reduced-motion— la préférence système, sa portée et ses limites - MDN —
Window.open()— pourquoi un appel hors geste utilisateur est bloqué - WCAG — Understanding 2.3.1 Three Flashes or Below Threshold — les seuils, et le cas des flashs rouges
- WCAG — Understanding 3.2.1 On Focus — le changement de contexte non demandé, dont le 13.2 dérive
- WCAG — Technique G19 — ne rien faire clignoter plus de trois fois par seconde