Saisie avec clavier
Aperçu : Saisie avec clavier
De nombreux types de technologies d’aide permettent de reproduire les fonctions d’un clavier, notamment les logiciels de reconnaissance vocale, les logiciels de commande au souffle et les claviers virtuels à l’écran, pour ne citer que ces exemples. En adoptant une conception de clavier accessible, vous assurez sa compatibilité avec un large éventail de technologies d’aide et de groupes d’utilisateurs.
L’accessibilité du clavier recoupe les sujets suivants :
- Ciblage clavier
Voir le module 3 > Navigation > Cible et ordre de cible > Quelle est la cible?
- Ordre de cible
Voir le module 3 > Navigation > Cible et ordre de cible > Ordre de cible
- Indicateur visuel de la cible
Voir module 3 > Liens > Indicateur visuel de la cible
- Fonctionnalité du clavier
- Pièges de clavier
Fonctionnalité du clavier
S’assurer que tout le contenu de la page peut être utilisé au moyen d’un clavier. La plupart des actions exécutées avec une souris ou un autre dispositif de pointage peuvent aussi être exécutées à partir du clavier (p. ex., cliquer, sélectionner, déplacer, dimensionner). Exemples de fonctionnalités :
- Utiliser des contrôles physiques tels que des liens, des menus, des boutons et des contrôles de formulaires (cases à cocher, boutons radio, saisie de texte, etc.).
- Utiliser des fonctions telles que le glisser-déposer, sélectionner du texte, le redimensionnement des zones ou l'affichage de menus contextuels.
- Exécuter des tâches telles que l'ajout ou le retrait d'un article dans un panier d'achat ou le lancement d'une session de chat avec un représentant commercial.
L'exception de toute action qui dépend de la trajectoire du mouvement de l'utilisateur (par exemple, un dessin à main levée tel qu'une signature). Ces actions ne peuvent pas être effectuées à partir du clavier.
L’utilisateur du clavier appuie normalement sur la touche de tabulation pour passer d’un élément interactif à l’autre – liens, boutons, champs texte, etc. Quand l’utilisateur accède à un élément avec la touche de tabulation, cet élément est « ciblé » et devient manipulable avec le clavier. D’autres touches, principalement les touches fléchées, déplacent la cible à l’intérieur des éléments complexes, ou groupes, composés de plusieurs sous-éléments actifs. D'autres touches, principalement les touches fléchées, permettent de déplacer le centre d'intérêt à l'intérieur des composants qui comprennent plusieurs éléments pouvant être mis au point. Par exemple, après avoir appuyé sur la touche Tab pour déplacer le focus sur un bouton radio d'un groupe, l'appui sur les touches fléchées déplace le focus parmi les boutons radio du groupe, et l'appui sur la touche Tab déplace le focus hors du groupe radio vers l'élément suivant dans la séquence de tabulation. Le chemin que suit le curseur quand l’utilisateur appuie sur la touche de tabulation est appelé la séquence de tabulation ou la boucle de tabulation.
Autres commandes clavier importantes :
- CTRL-L positionne la cible sur-le-champ d’adresse du navigateur.
- CTRL-W ferme un onglet
- CTRL-T ouvre un nouvel onglet
- La barre d'espacement fait défiler vers le bas un écran à la fois (Shift-Barre d'espacement fait défiler vers le haut).
- La barre d’espacement sélectionne les cases d’option et les cases à cocher
- La touche Entrée active un lien ou envoie un formulaire
- La barre d’espacement ou la touche Entrée active un bouton
Utilisation des liens et commandes HTML natifs
Dans la mesure du possible, utilisez des liens HTML et des contrôles de formulaires natifs plutôt que des éléments personnalisés. Les agents utilisateur fournissent le fonctionnement du clavier des liens HTML, des contrôles de formulaires, et les mappent à une API d'accessibilité. Les technologies d'assistance utilisent l'API d'accessibilité pour extraire et présenter des informations utiles, telles que le rôle, le nom, l'état et la valeur.
Commandes et liens HTML standard :
<a>
<fieldset>
<input>
Plusieurs types; voir le module 6 : Formulaires > Validation des types de saisie communs).
<select>
<textarea>
<button>
Utiliser l’événement onclick des ancrages et des boutons
Pour s’assurer que les utilisateurs du clavier puissent invoquer un script, utiliser des liens et des boutons HTML natifs avec l’événement onclick
. L’événement onclick
des deux éléments est indépendant du dispositif de saisie : il est lié à un clic de souris, à la touche Entrée et à la barre d’espacement.
HTML
Début du code
<button onclick="doStuff();">Do stuff</button>
<script>
function doStuff () {
alert('Button clicked');
}
</script>
Fin du code
Un bouton d’envoi situé à l’intérieur d’un formulaire<form>
ne nécessite pas de gestionnaire d’événement. Dans les deux cas suivants, la sélection du bouton d’envoi transmet le formulaire parent sans nécessiter le traitement séparé de l’événement onclick
. Ici, la valeur onsubmit
du formulaire déclenche la validation.
HTML
Début du code
<form onsubmit="handle_form_submission()">
[…]
<input type="submit" name="submit" value="Post your reply" />
Or:
<button type="submit" >Post your reply</button>
</form>
Fin du code
Jumeler les gestionnaires d’événement souris et les gestionnaires d’événement clavier
L’utilisation à la fois des événements clavier et des événements souris permet de rendre le contenu exploitable par un large éventail de dispositifs de saisie.
Le tableau suivant suggère les gestionnaires d’événement souris à jumeler aux gestionnaires d’événement clavier :
Utiliser … |
… avec |
---|---|
mousedown |
keydown |
mouseup |
keyup |
click |
keypress |
mouseover |
focus |
mouseout |
blur |
Lorsqu’ils utilisent un bouton ou un lien HTML natif, les agents utilisateurs traitent l’événement click
, qu’il a été activé avec la souris ou le clavier. Il n’est pas nécessaire de reproduire cet événement quand on ajoute des gestionnaires à des éléments HTML ciblables. Toutefois, à défaut de bouton ou de lien natif, il faut ajouter un événement keypress
.
Comme le gestionnaire d’événement keypress
réagit à n’importe quelle touche du clavier, il devrait d’abord vérifier si l’utilisateur a appuyé sur la touche Entrée avant de traiter l’événement. Autrement, il sera déclenché par n’importe quelle touche, même la touche de tabulation qui aurait été utilisée pour sortir de la commande.
En cas d’utilisation de l’attribut ARIA role="button"
au lieu des éléments natifs <button>
ou <input type="button">
, il faudra à la fois rendre l’élément ciblable et définir les gestionnaires d’événement pour le clic et les touches Entrée et barre d’espacement.
Bon example : Jumelage des événements souris et clavier
Dans cet exemple de lien d’image, l’image change lorsque l’utilisateur positionne le pointeur sur elle. Pour offrir aux utilisateurs du clavier une expérience similaire, l’image change également quand l’utilisateur l’atteint avec la touche de tabulation.
HTML
Début du code
<a href="menu.php"
onmouseover="swapImageOn('menu')"
onfocus="swapImageOn('menu')"
onmouseout="swapImageOff('menu')"
onblur="swapImageOff('menu')">
<img id="menu" src="menu_off.gif" alt="Menu" />
</a>
Javascript
Code begins
function swapImageOn(id){
document.getElementById(id).src='images/menu_on.png'
}
function swapImageOff(id){
document.getElementById(id).src='images/menu_off.png'
}
Fin du code
Mauvais exemple : Lien dépendant de la souris
Dans cet exemple, un lien d’image personnalisé réagit uniquement au clic de la souris et n’est pas activable par le clavier. Il n’y a pas de gestionnaire d’événement équivalent pour la touche Entrée. L’événement onclick
ne répond qu’aux saisies clavier appliquées à un bouton ou un lien HTML natif, et il s’agit d’un élément <img>
.
Le lien de l’image n’a pas d’attribut tabindex="0"
, ce qui l’empêche d’être ciblé avec le clavier.
Enfin, le lien de l’image ne comporte pas l’attribut role="link"
, qui indique sa nature de lien à la technologie d’aide.
L'exemple commence
L'exemple finit
HTML
Début du code
<img src="images/image1.png" class="img-link img-responsive" alt="Page suivante" onclick="window.location.href='index-fr.html')">>
Fin du code
CSS
Début du code
.img-link:hover { cursor: pointer; }
Fin du code
Bon example : Gestionnaires d’événement souris et clavier sur un bouton personnalisé
Dans cet exemple, un bouton personnalisé construit à partir d’un élément <span>
possède la sémantique et la fonctionnalité d’accessibilité nécessaires :
- Un attribut
tabindex="0"
pour pouvoir être ciblé avec le clavier. - Un attribut
role="button"
pour indiquer sa fonction à la technologie d’aide. - Un indicateur visuel de ciblage clavier et de survol par la souris au moyen du CSS.
- Un gestionnaire d’événement
onclick
pour l’activation par la souris. - Un gestionnaire d’événement
OnKeyDown
pour l’activation par le clavier. La fonction s’arrête si la touche actionnée n’est pas la barre d’espacement ou la touche Entrée.
Le JavaScript ajoute des noms à une liste sous le formulaire.
L'exemple commence
Ajouter nomL'exemple finit
HTML
Début du code
<label for="newName">Ajouter un nom</label>
<input type="text" id="newName">
<span role="button" tabindex="0" onclick="handleCommand(event)" onKeyDown="handleCommand(event)">Ajouter nom</span>
<ul id="nameList"></ul>
Fin du code
Voir le JavaScript
Début du code
function handleCommand(event) {
// Gère à la fois les clics de souris et le clavier
// Activer avec Entrée ou Espace
// Les pressions sur les touches autres que Entrée et Espace mettent fin au script
if (event instanceof KeyboardEvent
&& event.key !== 'Enter'
&& event.key !== ' ') {
return;
}
// Obtenez la nouvelle valeur du nom de l'élément d'entrée
let newNameInput = document.getElementById('newName');
let name = newNameInput.value;
// Effacer le champ de texte
newNameInput.value = '';
// Donner le focus au champ de texte pour permettre la saisie d'un nom supplémentaire
newNameInput.focus();
// N'ajoutez pas d'entrées vides à la liste
if(name.length > 0) {
listItem = document.createElement('li');
listItem.appendChild(document.createTextNode(name));
// Add the new name to the list
let list = document.getElementById('nameList');
list.appendChild(listItem);
}
}
Fin du code
Voir le CSS
Début du code
[role="button"] {
padding: 0.25em 0.5em;
background-color: #CCCCCC;
color: black;
margin-left: 5px;
outline: 2px solid white;
}
#newName:focus,
#newName:hover {
background-color: rgb(186, 228, 253);
}
[role="button"]:focus,
[role="button"]:hover {
outline: 2px dotted rgb(81, 81, 250);
}
Fin du code
Piège de clavier
Un piège à clavier se produit lorsqu'un utilisateur peut naviguer dans un composant ou un élément d'une page Web mais ne peut pas en sortir. Un exemple simple est une fenêtre pop-up (fenêtre modale ou lightbox) qui ne se ferme pas lorsque l'utilisateur appuie sur la touche Esc et dont le bouton de fermeture ne répond pas au clavier.
Assurez-vous que l'utilisateur peut entrer et sortir des éléments interactifs en utilisant uniquement le clavier.
Mauvais exemple : JavaScript focus() piège l’utilisateur du clavier
Cet exemple illustre les dangers du piège à clavier que représente l'utilisation de la méthode JavaScript focus()
. Le champ de saisie du formulaire utilise ici l'événement onblur
, qui est déclenché lorsque le focus quitte l'élément. Lorsque l'utilisateur du clavier appuie sur la touche Tab pour déplacer le focus du champ de saisie, l'événement onblur
se déclenche et remet le focus sur le champ de saisie, piégeant ainsi l'utilisateur.
HTML
Début du code
<label for="lastname">Last name</label>
<input id="lastname" type="text" value="" class="trap" onblur="this.focus();">
Fin du code
Mauvais exemple : JavaScript keydown() et event.preventDefault() piègent l’utilisateur du clavier
Cet exemple illustre les dangers du piège à clavier que représente un événement keypress JavaScript. La fonction JavaScript ne fait aucun effort pour détecter quelle touche a été enfoncée (elle devrait identifier la touche Entrée), elle se déclenche donc lorsque n'importe quelle touche est enfoncée. En outre, l'action par défaut associée à toute pression sur une touche est empêchée par event.preventDefault()
. Par conséquent, lorsqu'un utilisateur tente de déplacer le focus du lien en appuyant sur la touche Tab, l'événement keydown
se déclenche, l'action par défaut de la touche Tab (déplacement du focus vers l'élément suivant sur lequel le focus est possible) est empêchée, le focus reste sur le lien et une nouvelle fenêtre s'ouvre. L'utilisateur du clavier est pris au piège. Même le fait d'appuyer sur les touches Ctrl + Alt + Suppr dans Windows pour faire apparaître le gestionnaire de tâches échouera, car d'autres fenêtres seront simplement lancées en réponse à l'événement de frappe. L'ordinateur de l'utilisateur est détourné et, à moins qu'un collègue ou un ami ne puisse déplacer le focus de l'élément avec une souris, l'utilisateur est obligé de redémarrer l'ordinateur.
HTML
Début du code
<span class="trap link" role="link" tabindex="0" data-href="some-page.html">
Une page
</a>
Fin du code
JavaScript
Début du code
$(document).ready(function(){
$('span.trap').keydown(function(event){
event.preventDefault();
var href = $(this).attr('data-href');
var text = $(this).text();
window.open(href, text);
});
});
Fin du code
Gestion de cible avec contenu injecté de JavaScript
Le contenu ajouté à une page avec JavaScript peut se trouver à l’un des deux endroits suivants :
- Le contenu ajouté suit le déclencheur dans le DOM. Dans ce cas, il n'est pas nécessaire de gérer le focus. Lorsqu'il est activé, le contrôle déclencheur conserve le focus, et le contenu ajouté est le suivant dans l'ordre de lecture du lecteur d'écran et dans l'ordre des tabulations. Le contenu ajouté peut être positionné de manière absolue par le biais de CSS pour se trouver ailleurs sur la page.
- Le contenu ajouté ne suit pas le déclencheur dans le DOM. Dans ce cas, la cible doit être déplacée vers le contenu ajouté en utilisant la méthode JavaScript
focus()
. La cible doit avoir l’attributtabindex="-1"
. De plus, la cible doit avoir un contenu textuel ou un texte déterminé par programmation au moyen d’une étiquette, sinon un utilisateur de lecteur d’écran n’entendra rien à son arrivée. Si le contenu ajouté peut être réduit ou désactivé, la cible revient sur la commande de déclenchement (ou à un autre emplacement logique, selon le contexte). Éviter de perdre la cible ou de la réinitialiser au haut de la page.
Il y a des exceptions si vous mettez en œuvres certains modèles de composants graphiques décrits dans les Pratiques de rédaction ARIA (en anglais). Les auteurs de contenu doivent gérer le focus dans les rôles de conteneur suivants.
La gestion de la cible dans ces composants graphiques « composites » est une question distincte abordée dans le module 12.
Bon example : Gestion de la cible dans une application Web monopage
Dans cet exemple, une application Web monopage utilise JavaScript pour charger un article complet à l’intérieur de l’élément main
, sans chargement de la page. Les liens dans le menu de navigation déclenchent le chargement du contenu. Cet exemple ne comporte que quelques éléments de menu, mais les sites ont souvent des menus bien plus longs. Le déplacement de la cible est vite à un utilisateur de clavier la tâche fastidieuse de parcourir un menu avec la touche de tabulation pour accéder au contenu principal d’une application d’une seule page.
L’en-tête <h1>
de chaque page comporte l’attribut tabindex="-1"
qui permet le ciblage par les scripts. JavaScript identifie l’en-tête <h1>
au moyen d’un sélecteur de requête et pose la cible sur lui. Le script met également à jour l’élément <title>
de la page pour qu’il corresponde au texte de l’en-tête.
La première utilisation de JavaScript devrait être déclenchée par le menu et non par le chargement de la page. L’interaction initiale d’un utilisateur de lecteur d’écran avec la page devrait commencer par le haut, comme d’habitude.
HTML
Début du code
<nav>
<a href="/">Accueil</a>
<a href="/policies">Politiques</a>
<a href="/practices">Pratiques</a>
</nav>
<main>
// injecté:
<h1 tabindex="-1">Politiques</h1>
// reste du contenu injecté ...
</main>
Fin du code
JavaScript
Début du code
// Cela est appelé chaque fois que du nouveau contenu est chargé :
function onNewPage() {
var heading = document.querySelector('h1');
heading.focus();
// Mettre à jour le titre de la page
document.title = heading.textContent;
}
Fin du code
Bon example : Cible déplacée du déclencheur à une boîte de dialogue
Dans cet exemple, le fait d'appuyer sur le bouton de transcription de l'Ableplayer :
- lance un widget de dialogue ARIA contenant la transcription, et
- déplace le focus sur le premier bouton de la boîte de dialogue, celui des préférences de l'utilisateur. :
JavaScript
Début du code
this.$transcriptArea.find('button').first().focus();
Fin du code
Bon exemple : Cible gérée sur une boîte de dialogue au moyen d’une interaction au clavier
Dans cet exemple, quand l’utilisateur clique sur le bouton d’envoi, une fenêtre contextuelle s’ouvre et la cible est posée sur le premier élément actif de la fenêtre contextuelle. Quand l’utilisateur clique sur le bouton de fermeture de la fenêtre contextuelle, la cible retourne au bouton déclencheur.
L'exemple commence
L'exemple finit
Voir le HTML
Début du code
<h1>Modal Popup Example</h1>
<!-- Déclencher/ouvrir le modal -->
<button class="submit" id="myBtn">Submit</button>
<!-- Le modal -->
<div id="myModal" class="modal">
<!-- Le contenu modal -->
<div class="modal-content">
<h2>Votre formulaire a été soumis.</h2>
<button class="btn-close">Fermer</button>
</div>
</div>
Fin du code
Voir le CSS
Début du code
/* Le modal (arrière-plan) */
.modal {
display: none; /* Masqué par défaut */
position: fixed; /* Rester en place */
z-index: 1; /* S'asseoir sur le dessus */
padding-top: 100px; /* Emplacement de la boîte */
left: 0;
top: 0;
width: 100%; /* Pleine largeur */
height: 100%; /* Pleine hauteur */
}
/* Contenu modal */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 25%;
height:25%;
}
.submit {
background-color:#e60914;
border:0;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
color:#fff;
font-size: 15px;
padding: 10px 25px;
}
.submit:hover,
.submit:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
Fin du code
Voir le JavaScript
Début du code
// Obtenir le modal
var modal = document.getElementById("myModal");
// Obtenez le bouton qui ouvre le modal
var btnSubmit = document.getElementById("myBtn");
// Obtenez le bouton qui ferme le modal
var btnClose = document.getElementsByClassName("btn-close")[0];
// Lorsque l'utilisateur clique sur le bouton, ouvrez le modal.
btnSubmit.onclick = function() {
modal.style.display = "block";
}
}
//prevent tabbing to the page
btnClose.addEventListener("keydown", event => {
if (event.shiftKey || event.keyCode === 9) {
btnClose.focus();
event.preventDefault();
false;
}
});
// Lorsque l'utilisateur clique sur le bouton de fermeture, fermez le modal
btnClose.onclick = function() {
modal.style.display = "none";
}
// Lorsque l'utilisateur clique n'importe où en dehors de la modale, le fermer
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
document.addEventListener('keyup', function (event) {
if ( event.keyCode == 27 ) { //keycode 27 is escape
modal.style.display = "none";
btnSubmit.focus();
}
})
}
Fin du code
Ressources WCAG connexes
Ressources WCAG connexes
Critères de succès
Techniques
- G202 : Garantir le contrôle par le clavier pour toutes les fonctionnalités (en anglais)
- G90 : Fournir des événements déclenchés au clavier (en anglais)
- G21 : S'assurer que l'utilisateur n'est pas piégé dans le contenu (en anglais)
- H91 : Utiliser des éléments de formulaire et des liens HTML (en anglais)
- SCR20 : Utiliser à la fois des fonctions au clavier et spécifiques à d'autres périphériques (en anglais)
- SCR29 : Ajouter des actions au clavier accessibles à des éléments HTML statiques (en anglais)
- SCR35 : Rendre les actions au clavier accessibles en utilisant l'événement onclick sur les liens et les boutons (en anglais)
Échecs
- F54 : Échec du critère de succès 2.1.1 consistant à utiliser seulement des événements au pointeur (y compris par geste) pour une fonction (en anglais)
- F42 : Échec du critère de succès 1.3.1 et 2.1.1 consistant à utiliser des événements de scripts pour émuler des liens d'une manière qui n'est pas déterminable par un programme informatique (en anglais)