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 :

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

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 :

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

<button onclick="doStuff();">Do stuff</button>
<script>
   function doStuff () {
      alert('Button clicked');
   }
</script>

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

<form onsubmit="handle_form_submission()">
   […]
   <input type="submit" name="submit" value="Post your reply" />
   Or:
   <button type="submit" >Post your reply</button>
</form>

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 :

Correspondance des gestionnaires d’événement

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.

Menu

HTML

<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

function swapImageOn(id){
	document.getElementById(id).src='images/menu_on.png'
}
function swapImageOff(id){
	document.getElementById(id).src='images/menu_off.png'
}	

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.

Page suivante

HTML

<img src="images/image1.png" class="img-link img-responsive" alt="Page suivante" onclick="window.location.href='index-fr.html')">>

CSS

.img-link:hover { cursor: pointer; }

 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.

Ajouter nom

    HTML

    <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>
    Voir le JavaScript
    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);
       }
    }
    Voir le CSS
    [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);
    }

    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

    <label for="lastname">Last name</label>
    <input id="lastname" type="text" value="" class="trap" onblur="this.focus();">

     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

    <span class="trap link" role="link" tabindex="0" data-href="some-page.html">
       Une page
    </a>

    JavaScript

    $(document).ready(function(){   
       $('span.trap').keydown(function(event){ 
          event.preventDefault();
          var href = $(this).attr('data-href');        
          var text = $(this).text();
          window.open(href, text);    
       });
    });

    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’attribut tabindex="-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

    <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>

    JavaScript

    // 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; 
      }

     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

      this.$transcriptArea.find('button').first().focus();
    Screenshot of Able Player

    Exemple externe : Able Player Video Demo #3

    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.

    Voir le HTML
    <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>
    Voir le CSS
    /* 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;
    }
    Voir le JavaScript
    // 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();
      }
    })
    }

    Ressources WCAG connexes

    Ressources WCAG connexes

    Critères de succès

    Techniques

    Échecs

    Haut de la page