Passer au contenu

Accessibilité

L'accessibilité numérique (en abrégé a11y) fait référence aux pratiques visant à créer des sites web qui peuvent être utilisés par toutes les personnes — qu'elles aient un handicap, une connexion lente, du matériel ancien ou défectueux ou simplement un environnement défavorable. Par exemple, ajouter des sous-titres à une vidéo peut aider vos utilisateurs sourds et malentendants ainsi que ceux dans un environnement bruyant et qui ne peuvent pas entendre leur téléphone. De la même façon, s'assurer que le contraste de votre texte n'est pas trop bas aidera les utilisateurs déficients visuels ainsi que ceux qui utilisent leur téléphone en plein soleil.

Par où commencer ?

Visitez le guide de planification et pilotage de la prise en compte de l’accessibilité Web (en anglais) proposé par le World Wide Web Consortium (W3C)

Vous devez ajouter un lien en haut de chaque page qui mène directement à la zone de contenu principale afin que les utilisateurs puissent ignorer les zones de regroupement de contenus répétées sur plusieurs pages web.

Typiquement, cela se fait en haut de App.vue car ce sera le premier élément pouvant être ciblé sur toutes vos pages :

template
<ul class="skip-links">
  <li>
    <a href="#main" ref="skipLink" class="skip-link">Skip to main content</a>
  </li>
</ul>

Pour masquer le lien lorsqu'il n'est pas ciblé, vous pouvez ajouter le style suivant :

css
.skip-link {
  white-space: nowrap;
  margin: 1em auto;
  top: 0;
  position: fixed;
  left: 50%;
  margin-left: -72px;
  opacity: 0;
}
.skip-link:focus {
  opacity: 1;
  background-color: white;
  padding: 0.5em;
  border: 1px solid black;
}

Lorsque qu'un utilisateur change d'itinéraire, redonnez le focus sur le lien d'évitement. Cela peut être réalisé en appelant focus sur la ref de template du lien d'évitement (en supposant l'utilisation de vue-router) :

vue
<script>
export default {
  watch: {
    $route() {
      this.$refs.skipLink.focus()
    }
  }
}
</script>
vue
<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()
const skipLink = ref()

watch(
  () => route.path,
  () => {
    skipLink.value.focus()
  }
)
</script>

Lisez la documentation à propos des liens d'évitement vers le contenu principal

Structuration de l'information

L'un des éléments les plus importants de l'accessibilité est de s'assurer que le design peut soutenir une mise en œuvre accessible. Le design doit tenir compte non seulement du contraste des couleurs, de la sélection des polices, du dimensionnement du texte et de la langue, mais également de la structure du contenu dans l'application.

Titres

Les utilisateurs peuvent naviguer dans une application à travers les titres. Le fait d'avoir des titres descriptifs pour chaque section de votre application permet aux utilisateurs de prédire plus facilement le contenu de celle-ci. En ce qui concerne les titres, il existe quelques pratiques d'accessibilité recommandées :

  • Imbriquez les titres dans leur ordre hiérarchique : <h1> - <h6>
  • Ne sautez pas les titres à l'intérieur d'une section
  • Utilisez les balises de titres plutôt que du style de texte pour représenter visuellement des titres.

En lire plus à propos des titres

template
<main role="main" aria-labelledby="main-title">
  <h1 id="main-title">Main title</h1>
  <section aria-labelledby="section-title-1">
    <h2 id="section-title-1"> Section Title </h2>
    <h3>Section Subtitle</h3>
    <!-- Contenu -->
  </section>
  <section aria-labelledby="section-title-2">
    <h2 id="section-title-2"> Section Title </h2>
    <h3>Section Subtitle</h3>
    <!-- Contenu -->
    <h3>Section Subtitle</h3>
    <!-- contenu -->
  </section>
</main>

Landmarks

Les rôles ARIA landmark permettent d'accéder programmatiquement aux sections d'une application. Les utilisateurs qui s'appuient sur des technologies d'assistance peuvent naviguer vers chaque section de l'application et passer d'un contenu à l'autre. Vous pouvez utiliser les rôles ARIA pour vous aider à atteindre ce résultat.

HTMLRôle ARIABut du landmark
headerrole="banner"Entête principal : titre de la page.
navrole="navigation"Collection de liens utilisables lors de la navigation dans le document ou vers des documents associés
mainrole="main"Le contenu central ou principal du document.
footerrole="contentinfo"Information à propos du document parent : notes de pied de page/copyrights/liens vers la déclaration de confidentialité
asiderole="complementary"Supporte le contenu principal, malgré tout est séparé et a du sens par lui-même
searchrole="search"Cette section contient la fonctionnalité de recherche pour l'application
formrole="form"Collection d'éléments associés à un formulaire
sectionrole="region"Contenus pertinents vers lesquels les utilisateurs sont susceptibles de naviguer. Un libellé doit être fourni pour cet élément

Aller plus loin à propos des landmarks

Formulaires sémantiques

Lors de la création d'un formulaire, vous pouvez utiliser les éléments suivants : <form>, <label>, <input>, <textarea>, et <button>

Les labels sont en général placés en haut ou à gauche des champs de formulaire :

template
<form action="/dataCollectionLocation" method="post" autocomplete="on">
  <div v-for="item in formItems" :key="item.id" class="form-item">
    <label :for="item.id">{{ item.label }} : </label>
    <input
      :type="item.type"
      :id="item.id"
      :name="item.id"
      v-model="item.value"
    />
  </div>
  <button type="submit">Submit</button>
</form>

Remarquez comment vous pouvez inclure autocomplete='on' sur l'élément de formulaire et il sera appliqué à tous les input de votre formulaire. Vous pouvez aussi positionner différentes valeurs pour l'attribut autocomplete pour chaque input.

Labels

Utilisez des labels pour décrire le but de chaque contrôle de formulaire ; en liant for et id.

template
<label for="name">Name: </label>
<input type="text" name="name" id="name" v-model="name" />

Si vous inspectez cet élément dans vos Outils de développement Chrome et que vous ouvrez l'onglet Accessibilité dans l'onglet Éléments, vous verrez comment le champ prend son nom du label :

Attention :

Vous pourriez avoir vu cette façon d'envelopper un champ de saisie par un label :

template
<label>
  Name:
  <input type="text" name="name" id="name" v-model="name" />
</label>

Associer les labels avec un id correspondant est mieux supporté par les technologies d'assistance.

aria-label

Vous pouvez aussi donner un nom accessible au champ avec aria-label.

template
<label for="name">Name: </label>
<input
  type="text"
  name="name"
  id="name"
  v-model="name"
  :aria-label="nameLabel"
/>

N'hésitez pas à inspecter cet élément dans les outils de développeur de Chrome pour voir comment le nom accessible a changé :

Outils de développement de Chrome montrant le nom accessible d'un champs via aria-label

aria-labelledby

Utiliser aria-labelledby est similaire à aria-label à l'exception du fait que c'est utilisé si le libellé est visible à l'écran. Associez-le à d'autres éléments par leurs id et vous pourrez associer plusieurs id:

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <h1 id="billing">Billing</h1>
  <div class="form-item">
    <label for="name">Name: </label>
    <input
      type="text"
      name="name"
      id="name"
      v-model="name"
      aria-labelledby="billing name"
    />
  </div>
  <button type="submit">Submit</button>
</form>

Outils de développeur de Chrome montrant le nom du champs accessible via aria-labelledby

aria-describedby

L'attribut aria-describedby est utilisé de la même manière que aria-labelledby à l'exception qu'il fournit une description avec de l'information supplémentaire pour l'utilisateur. Cela peut être utilisé pour décrire le critère pour n'importe quel champ :

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <h1 id="billing">Billing</h1>
  <div class="form-item">
    <label for="name">Full Name: </label>
    <input
      type="text"
      name="name"
      id="name"
      v-model="name"
      aria-labelledby="billing name"
      aria-describedby="nameDescription"
    />
    <p id="nameDescription">Please provide first and last name.</p>
  </div>
  <button type="submit">Submit</button>
</form>

Vous pouvez voir la description en inspectant depuis les outils de développeur Chrome :

Outils de développeur Chrome montrant un nom de champs accessible depuis aria-labelledby et décrit avec aria-describedby

Placeholder

Évitez d'utiliser des placeholders car ils perturbent beaucoup d'utilisateurs.

Un des problèmes avec les placeholders est qu'ils ne remplissent pas les critères de contraste de couleur par défaut ; corriger le contraste de couleur donne l'impression que le champ est pré-rempli avec une valeur. En regardant l'exemple suivant, vous pouvez voir que le placeholder Last Name conforme aux critères de contraste semble être pré-rempli :

Placeholder accessible

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <div v-for="item in formItems" :key="item.id" class="form-item">
    <label :for="item.id">{{ item.label }} : </label>
    <input
      type="text"
      :id="item.id"
      :name="item.id"
      v-model="item.value"
      :placeholder="item.placeholder"
    />
  </div>
  <button type="submit">Submit</button>
</form>
css
/* https://www.w3schools.com/howto/howto_css_placeholder.asp */

#lastName::placeholder {
  /* Chrome, Firefox, Opera, Safari 10.1+ */
  color: black;
  opacity: 1; /* Firefox */
}

#lastName:-ms-input-placeholder {
  /* Internet Explorer 10-11 */
  color: black;
}

#lastName::-ms-input-placeholder {
  /* Microsoft Edge */
  color: black;
}

Il vaut mieux fournir toutes les informations dont l'utilisateur a besoin pour remplir les formulaires à l'extérieur des champs de saisie.

Instructions

Lorsque vous ajoutez des instructions pour vos champs de saisie, assurez-vous de les associer correctement aux champs de saisie. Vous pouvez fournir des instructions complémentaires et associer plusieurs ids à l'intérieur d'un aria-labelledby. Cela permet un design plus flexible.

template
<fieldset>
  <legend>Using aria-labelledby</legend>
  <label id="date-label" for="date">Current Date: </label>
  <input
    type="date"
    name="date"
    id="date"
    aria-labelledby="date-label date-instructions"
  />
  <p id="date-instructions">MM/DD/YYYY</p>
</fieldset>

De façon alternative, vous pouvez attacher les instructions au champ avec aria-describedby:

template
<fieldset>
  <legend>En utilisant aria-describedby</legend>
  <label id="dob" for="dob">Date de naissance : </label>
  <input type="date" name="dob" id="dob" aria-describedby="dob-instructions" />
  <p id="dob-instructions">DD/MM/YYYY</p>
</fieldset>

Cacher du contenu

En règle générale, il n'est pas recommandé de cacher visuellement des labels, même si le champ est un nom accessible. Cependant, si la fonctionnalité du champ peut être comprise à l'aide du contenu alentour, alors, nous pouvons cacher le libellé visuel.

Regardons ce champ de recherche :

template
<form role="search">
  <label for="search" class="hidden-visually">Search: </label>
  <input type="text" name="search" id="search" v-model="search" />
  <button type="submit">Search</button>
</form>

Nous pouvons faire cela, car le bouton de recherche va aider les utilisateurs visuels à identifier le but du champ de saisie.

Nous pouvons utiliser du CSS pour cacher visuellement des éléments, mais les laisser disponibles pour les technologies d'assistance :

css
.hidden-visually {
  position: absolute;
  overflow: hidden;
  white-space: nowrap;
  margin: 0;
  padding: 0;
  height: 1px;
  width: 1px;
  clip: rect(0 0 0 0);
  clip-path: inset(100%);
}

aria-hidden="true"

Ajouter aria-hidden="true" va cacher l'élément aux technologies d'assistance, mais les laissera disponibles visuellement pour les autres utilisateurs. Ne l'utilisez pas pour des éléments sur lesquels il est possible de faire le focus, uniquement sur des éléments décoratifs ou du contenu hors écran.

template
<p>This is not hidden from screen readers.</p>
<p aria-hidden="true">This is hidden from screen readers.</p>

Boutons

Lorsque vous utilisez des boutons à l'intérieur d'un formulaire, vous devez en indiquer le type afin d'éviter la soumission du formulaire. Vous pouvez aussi utiliser un input pour créer des boutons :

template
<form action="/dataCollectionLocation" method="post" autocomplete="on">
  <!-- Boutons -->
  <button type="button">Cancel</button>
  <button type="submit">Submit</button>

  <!-- Input buttons -->
  <input type="button" value="Cancel" />
  <input type="submit" value="Submit" />
</form>

Images fonctionnelles

Vous pouvez utiliser cette technique pour créer des images fonctionnelles.

  • Champs de saisie

    • Ces images feront office de boutons de soumission pour les formulaires
    template
    <form role="search">
      <label for="search" class="hidden-visually">Search: </label>
      <input type="text" name="search" id="search" v-model="search" />
      <input
        type="image"
        class="btnImg"
        src="https://img.icons8.com/search"
        alt="Search"
      />
    </form>
  • Icônes

template
<form role="search">
  <label for="searchIcon" class="hidden-visually">Search: </label>
  <input type="text" name="searchIcon" id="searchIcon" v-model="searchIcon" />
  <button type="submit">
    <i class="fas fa-search" aria-hidden="true"></i>
    <span class="hidden-visually">Search</span>
  </button>
</form>

Standards

Le World Wide Web Consortium (W3C) Web Accessibility Initiative (WAI) développe les standards d'accessibilité pour les différents composants :

Web Content Accessibility Guidelines (WCAG)

WCAG 2.1 étend WCAG 2.0 et permet l'implémentation de nouvelles technologies en tenant compte de l'évolution du web. Le W3C encourage l'utilisation de la version la plus récente de WCAG lors du développement ou de la mise à jour de vos pratiques d'accessibilité Web.

WCAG 2.1 Quatre principaux principes de guidance (POUR en abrégé) :

  • Perceptible
    • Les utilisateurs doivent être capables de percevoir l'information qui leur est présentée
  • Utilisable
    • Les formulaires, contrôles et navigation de l'interface sont utilisables
  • Compréhensible
    • Les informations et l’utilisation de l’interface utilisateur doivent être compréhensibles par tous les utilisateurs
  • Robuste
    • Les utilisateurs doivent pouvoir continuer d'accéder au contenu au fur et à mesure que la technologie avance

Web Accessibility Initiative – Accessible Rich Internet Applications (WAI-ARIA)

WAI-ARIA du W3C fournit des conseils sur comment construire du contenu dynamique et des contrôles avancés d'interface utilisateur.

Resources

Documentation

Technologies d'assistance

Tester l'accessibilité

Utilisateurs

L'Organisation Mondiale de la Santé estime que 15% de la population mondiale est atteinte d'une forme de handicap, 2-4% d'entre elle de handicaps sévères. Ceci est estimé à 1 milliard de personnes dans le monde ; faisant des personnes avec un handicap la plus grande minorité au monde.

Il y a un large spectre de handicaps, qui peut être divisé grosso-modo en quatre catégories :

  • Visuel - Ces utilisateurs peuvent bénéficier de l'utilisation de liseurs d'écran, d'outils d'agrandissement, du contrôle du contraste ou de plage braille.
  • Auditif - Ces utilisateurs peuvent bénéficier de sous-titres, de transcriptions ou de vidéos en langages des signes.
  • Moteur - Ces utilisateurs peuvent bénéficier d'un large spectre de technologies d'assistance pour les assistive technologies for handicaps moteurs  : logiciels de reconnaissance vocale, eye tracking, accès par bouton unique, head wand, sip and puff switch, souris trackball surdimensionnée, clavier adaptatif ou autres technologies d'assistance.
  • Cognitif - Ces utilisateurs peuvent bénéficier de média supplémentaire, d'une organisation structurelle du contenu, d'un style d'écriture clair et simple.

Rendez-vous aux liens suivants de WebAim pour comprendre via des retours d'expérience d'utilisateurs :

Accessibilitéa chargé