Créer des applications Angular plus accessibles

b23a30a52c1169e4.png

L'accessibilité est un élément essentiel du développement Web. Il permet aux utilisateurs de percevoir, de comprendre, de parcourir et d'utiliser les applications. De fait, un adulte américain sur quatre est atteint d'un handicap qui a un impact sur les activités principales de sa vie quotidienne. À l'échelle mondiale, environ 15 % de la population, soit plus d'un milliard de personnes, ont une certaine forme de handicap, et 2 à 4 % d'entre elles rencontrent des difficultés importantes.

Les handicaps courants ayant un impact sur l'utilisation du Web incluent la cécité et la déficience visuelle, la surdité et les problèmes auditifs, la motricité réduite, le handicap cognitif et le daltonisme, pour n'en citer que quelques-uns.

Dans ce cours, "a11y" est la forme abrégée du mot anglais "accessibility" (accessibilité) : vous remarquerez que la lettre a est suivie de 11 caractères, puis d'un y.

Pour une présentation détaillée des problèmes et des techniques de conception d'applications accessibles, consultez Accessibilité.

Objectifs de l'atelier

  • Appliquer les bonnes pratiques et utiliser des techniques intégrées pour résoudre des problèmes courants d'accessibilité sur le Web à l'aide d'une application Angular de démonstration dédiée à un restaurant de dumplings
  • Respecter toutes les consignes d'accessibilité (WCAG 2.0 et ARIA 1.2), et effectuer des audits axe et Lighthouse de l'accessibilité

818cc91d17fae486.png 510ca511c265da81.png

Points abordés

Vous allez découvrir huit problèmes d'accessibilité courants dans les applications Angular ayant une incidence sur les utilisateurs. Vous apprendrez également à les identifier et à les résoudre. Plus spécifiquement, vous allez :

  • effectuer un audit de l'accessibilité de votre application à l'aide des outils pour les développeurs Google Chrome, de Lighthouse et d'axe ;
  • résoudre les problèmes des applications monopages avec des titres de pages uniques ;
  • résoudre les problèmes de contraste des couleurs trop faible pour les utilisateurs malvoyants ;
  • utiliser le HTML sémantique pour vous assurer que les lecteurs d'écran peuvent parcourir la page sans encombre ;
  • utiliser Angular Material et des commandes non imbriquées pour que les lecteurs d'écran puissent accéder à toutes les commandes ;
  • ajouter la compatibilité avec ARIA pour les lecteurs d'écran ;
  • importer et utiliser le package a11y du CDK Angular ;
  • utiliser FocusTrap pour que les lecteurs d'écran puissent parcourir un composant personnalisé ;
  • publier une notification avec l'outil LiveAnnouncer du CDK ;
  • détecter les utilisateurs employant le mode Contraste élevé et implémenter des thèmes contrastés.

Prérequis

Obtenir le code

Tous les éléments dont vous avez besoin pour ce projet se trouvent dans un dépôt GitHub. Pour commencer, clonez le code, puis ouvrez-le dans l'environnement de développement de votre choix.

Cloner le dépôt et diffuser l'application

Nous vous recommandons d'utiliser VSCode ou un IDE local pour cet atelier de programmation.

  1. Ouvrez un nouvel onglet dans votre navigateur pour accéder à l'adresse https://github.com/googlecodelabs/angular-accessibility.
  2. Dupliquez et clonez le dépôt, puis répétez l'opération pour cd angular-accessibility/ dans le dépôt.
  3. Accédez à la branche de code de démarrage git checkout get-started.
  4. Ouvrez le code dans VSCode ou dans l'IDE de votre choix.
  5. Exécutez npm install pour installer les dépendances nécessaires à l'exécution du serveur.
  6. Exécutez le serveur avec la commande ng serve.
  7. Ouvrez http://localhost:4200 dans un nouvel onglet de votre navigateur.

Point de départ

Vous allez utiliser une application de restaurant basique conçue spécialement pour cet atelier de programmation. Nous avons simplifié le code pour montrer les concepts abordés dans cet atelier de programmation, c'est pourquoi il offre peu de fonctionnalités.

93a2d45cdd58d830.png

Explorer la démo

Pour commencer, explorez les trois fonctionnalités de votre application :

  1. À l'aide de la barre de navigation, consultez les routes Our Shop (Notre restaurant), Our Story (Notre histoire) et Find Us (Nous trouver), et consultez les informations sur le restaurant de dumplings.
  2. Changez de thème pour alterner entre les modes clair et sombre.
  3. Personnalisez la garniture, la quantité et la couleur de votre commande de dumplings.
  4. Sélectionnez Purchase (Acheter) pour enregistrer votre commande personnalisée dans la console.

Utiliser Angular pour résoudre les problèmes courants d'accessibilité sur le Web

Dans cet atelier de programmation, vous allez vous consacrer à l'accessibilité des fonctionnalités existantes de l'application. Vous commencerez par identifier les problèmes d'accessibilité qu'elle présente, puis les corriger pour que l'icône 🛑 se transforme en ✅.

Identifier les problèmes à corriger

Pour chaque exemple, identifiez d'abord le problème d'accessibilité qui se pose à l'aide de tests manuels et automatiques.

En l'état actuel du Web, vous devez obligatoirement tester l'accessibilité manuellement.

Il existe des outils capables d'identifier les problèmes d'accessibilité, mais aucun d'eux ne peut garantir qu'une application est entièrement accessible. Les tests manuels vous permettent de contrôler divers concepts d'accessibilité comme le classement logique des contenus et la parité des fonctionnalités.

Tests manuels

Dans le cadre de cet atelier, vous devrez activer le lecteur d'écran intégré à votre ordinateur, puis parcourir les pages via la navigation avec le clavier afin de tester manuellement l'accessibilité de l'application. Pour plus d'informations, consultez Sémantique et lecteurs d'écran.

Entraînez-vous en activant le lecteur d'écran et en parcourant l'écran.

Vous pouvez utiliser la fonctionnalité VoiceOver intégrée à MacOS. Pour l'activer, cliquez sur Préférences Système > Accessibilité > VoiceOver > Activer VoiceOver. Pour activer ou désactiver la fonctionnalité, appuyez rapidement sur Touch ID trois fois de suite tout en appuyant sur la touche Command de manière prolongée.

Pendant ce cours, vous effectuerez principalement des tests manuels. Vous utiliserez des outils automatiques pour contrôler des fonctionnalités spécifiques qui peuvent être automatisées.

Tests automatiques

Vous allez également utiliser quelques outils pour les développeurs en vue d'automatiser votre application et de d'effectuer son audit. Ces outils vous permettront de contrôler différents éléments tels que la présence de texte alternatif sur une image ou le rapport de contraste de la couleur du texte. Ils fonctionnent comme des lints et peuvent reconnaître la présence d'un texte alternatif. Vous devez toutefois vérifier manuellement que le contenu est logique et pertinent.

Lighthouse et outils pour les développeurs Chrome

  1. Ouvrez les outils pour les développeurs Chrome.
  2. Sélectionnez l'onglet Lighthouse, puis cochez la case Accessibility (Accessibilité).
  3. Cliquez sur Generate report (Générer un rapport) pour réaliser un audit Lighthouse sur l'accessibilité.

3935811012517f4e.png

axe

  1. Installez l'extension axe DevTools. Vous devrez peut-être redémarrer votre navigateur pour que l'extension s'affiche.
  2. Ouvrez les outils pour les développeurs Chrome.
  3. Accédez à l'onglet axe DevTools, puis sélectionnez Scan all of my page (Scanner toute la page) pour exécuter une analyse axe DevTools.

7033f0ef4c1c3210.png

Linting

Vous pouvez utiliser les règles Angular ESLint pour effectuer une analyse lint de votre code et rechercher des attributs d'accessibilité pouvant être automatisés.

Dans .eslintrc.json, ajoutez le code suivant, qui concerne l'accessibilité :

"@angular-eslint/template/accessibility-alt-text": 2,
"@angular-eslint/template/accessibility-elements-content": 2,
"@angular-eslint/template/accessibility-label-for": 2,
"@angular-eslint/template/no-positive-tabindex": 2,
"@angular-eslint/template/accessibility-table-scope": 2,
"@angular-eslint/template/accessibility-valid-aria": 2,
"@angular-eslint/template/click-events-have-key-events": 2,
"@angular-eslint/template/mouse-events-have-key-events": 2,
"@angular-eslint/template/no-autofocus": 2,
"@angular-eslint/template/no-distracting-elements": 2

Pour en savoir plus, consultez les dernières règles ESLint sur GitHub.

Votre point de départ

Ces nouvelles méthodes de test vous permettent d'identifier les problèmes suivants dans votre application grâce aux audits Lighthouse et axe, et à la fonctionnalité VoiceOver manuelle :

1356f16f5505c9c9.png

Audit de l'accessibilité :

  • 🛑 Toutes les pages ont le même titre
  • 🛑 Les couleurs des éléments doivent être suffisamment contrastées
  • 🛑 Les éléments HTML doivent avoir un ordre, un nom et un rôle logiques
  • 🛑 Les lecteurs d'écran ne peuvent pas sélectionner les cases à cocher imbriquées
  • 🛑 Les lecteurs d'écran ne peuvent pas lire les valeurs de curseur
  • 🛑 Dans le sélecteur de couleur, le curseur du lecteur d'écran sort de la boîte de dialogue
  • 🛑 Les modifications, erreurs et notifications ne sont pas annoncées
  • 🛑 Le mode Contraste élevé n'est pas activé

En fournissant des titres de page uniques et concis, vous permettez aux utilisateurs de services d'accessibilité de comprendre rapidement le contenu et l'objectif d'une page Web. Ces titres sont essentiels pour les personnes souffrant d'un handicap visuel, car ce sont les premiers éléments d'une page qui sont annoncés par les logiciels de lecture d'écran.

Angular est une application monopage. Par conséquent, la plupart des transitions (le passage à une nouvelle page, par exemple) n'entraînent pas l'actualisation de la page. Cela signifie qu'en l'absence de modifications, chaque page est lue avec un titre identique, ce qui empêche d'en déterminer le contenu et l'objectif.

À la fin de cette section, votre application ne présentera plus le problème suivant :

  • 🛑 Toutes les pages ont le même titre

Les instructions sont disponibles sous les commentaires : TODO: #4. Define unique page titles.

Identifier le problème

Pour identifier le problème, vous devrez activer votre lecteur d'écran, puis parcourir les onglets Our Shop (Notre restaurant), Our Story (Notre histoire) et Find Us (Nous trouver) pour voir le titre des pages :

  1. Activez VoiceOver.
  2. Naviguez entre les pages à l'aide de la touche Tabulation.
  3. Assurez-vous que le titre de la page est toujours accessible dans Angular.

Le titre de votre page doit être unique pour que les internautes puissent rapidement en comprendre le sujet sans avoir à la parcourir.

cb92438126bb2be8.png

Ajouter des titres de page pertinents

Si vous modifiez une page ou une vue, assurez-vous de changer le titre en conséquence. Pour cela, utilisez le service Title d'Angular, qui permet de définir des titres uniques pour toutes vos pages.

  1. Ajoutez un titre unique à chacune des trois routes définies :

src/app/app-routing.module.ts

const routes: Routes = [
  { path: 'shop', component: ShopComponent, data: {title: 'Our Shop – a11y in Angular'} },
  { path: 'about', component: AboutComponent, data: {title: 'Our Story - a11y in Angular'} },
  { path: 'locate', component: LocationComponent, data: {title: 'Find Us - a11y in Angular'} },
  { path: '',   redirectTo: '/shop', pathMatch: 'full' },
  { path: '**', component: ShopComponent },
];
  1. Utilisez le service Title pour configurer le titre de la page en fonction des données de la route :

src/app/app.component.ts

import { Title } from '@angular/platform-browser';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { filter, map } from 'rxjs/operators';

export class AppComponent implements OnInit {
  title = 'a11y in Angular';

  constructor(private titleService: Title,
              private router: Router,
              private activatedRoute: ActivatedRoute) {}

  ngOnInit(): void {
    const appTitle = this.titleService.getTitle();
    this.router
      .events.pipe(
        filter(event => event instanceof NavigationEnd),
        map(() => {
          const child = this.activatedRoute.firstChild;
          if (child?.snapshot.data.title) {
            return child?.snapshot.data.title;
          }
          return appTitle;
        })
      ).subscribe((title: string) => {
        this.titleService.setTitle(title);
      });
  }
}

Vérifier les modifications

Activez à nouveau votre lecteur d'écran, puis vérifiez les modifications. Désormais, chaque page présente un titre unique.

5a85fdb689464137.png

Audit de l'accessibilité :

  •  Le titre de chaque page est unique
  • 🛑 Les couleurs des éléments doivent être suffisamment contrastées
  • 🛑 Les éléments HTML doivent avoir un ordre, un nom et un rôle logiques
  • 🛑 Les lecteurs d'écran ne peuvent pas sélectionner les cases à cocher imbriquées associées à des fruits
  • 🛑 Les lecteurs d'écran ne peuvent pas lire les valeurs de curseur
  • 🛑 Dans le sélecteur de couleur, le curseur du lecteur d'écran sort de la boîte de dialogue
  • 🛑 Les modifications, erreurs et notifications ne sont pas annoncées
  • 🛑 Le mode Contraste élevé n'est pas activé

Les graphismes attrayants sont appréciables, mais vous devez vous assurer que les personnes malvoyantes (comme celles atteintes de daltonisme) peuvent lire vos contenus. Les règles pour l'accessibilité des contenus Web WCAG 2.0 établissent des normes de rapport de contraste des couleurs pour rendre les contenus Web plus accessibles. Dans Angular comme sur le Web, vous pouvez définir des palettes de couleurs qui assurent la conformité de vos composants avec ces normes, et qui sont visibles par les utilisateurs malvoyants et daltoniens.

À la fin de cette section, votre application ne présentera plus le problème suivant :

  • 🛑 Les couleurs des éléments doivent être suffisamment contrastées

Les instructions sont disponibles sous les commentaires : TODO: #5. Ensure adequate color contrast.

Identifier les problèmes de contraste trop faible à l'aide des outils pour les développeurs Chrome

Pour identifier ce problème, vous devrez inspecter les éléments de votre application avec les outils pour les développeurs Chrome.

  1. Utilisez l'outil d'inspection pour afficher les boutons en forme d'icônes du menu. Vous pouvez constater que le contraste est de 1,85, ce qui est bien en dessous des exigences WCAG.

b2e27bca38a1649c.png

  1. Exécutez le rapport d'audit de l'accessibilité dans Lighthouse ou l'analyse axe afin d'identifier les problèmes de rapport de contraste.

c1cbc422fcdc89b.png

Modifier la couleur du thème Material

Le jeu de couleurs de votre composant est défini dans votre thème Material personnalisé. Vous devez mettre à jour la valeur de votre thème de façon à respecter les normes de rapport de contraste des couleurs.

Modifiez votre thème Material pour utiliser une couleur de texte plus sombre qui augmentera le rapport de contraste des icônes :

src/styles.scss

$light-primary: mat.define-palette(mat.$pink-palette, $default: A100, $lighter: 100, $text: 900);

Pour trouver une couleur qui respecte les normes ou pour mettre à jour les valeurs de couleur individuelles en Sass, vous pouvez également utiliser l'outil d'accessibilité intégré pour les développeurs Chrome.

Vérifier les modifications

Inspectez à nouveau vos éléments pour confirmer vos modifications. Désormais, les couleurs présentent un rapport de contraste suffisant.

a990337d9f3127fd.png

Audit de l'accessibilité :

  •  Le titre de chaque page est unique
  •  Les couleurs présentent un rapport de contraste suffisant
  • 🛑 Les éléments HTML doivent avoir un ordre, un nom et un rôle logiques
  • 🛑 Les lecteurs d'écran ne peuvent pas sélectionner les cases à cocher imbriquées associées à des fruits
  • 🛑 Les lecteurs d'écran ne peuvent pas lire les valeurs de curseur
  • 🛑 Dans le sélecteur de couleur, le curseur du lecteur d'écran sort de la boîte de dialogue
  • 🛑 Les modifications, erreurs et notifications ne sont pas annoncées
  • 🛑 Le mode Contraste élevé n'est pas activé

Les éléments HTML natifs enregistrent des schémas d'interaction standards essentiels en matière d'accessibilité. Bien qu'un paragraphe puisse apparaître comme un élément <span>, et un élément <div> comme un bouton, l'élément HTML sémantique fait en sorte que les lecteurs d'écran et la navigation au clavier comprennent les interactions et les commandes du HTML.

Lorsque vous créez des composants Angular, réutilisez directement ces éléments natifs si vous le pouvez plutôt que de réintégrer des comportements compatibles. Ainsi, la page disposera d'une structure de contenu adaptée et d'un flux de contenu naturel. La navigation avec la touche Tabulation suivra un ordre logique qui permettra aux utilisateurs de parcourir efficacement le site avec leur clavier.

À la fin de cette section, votre application ne présentera plus le problème suivant :

  • 🛑 Les éléments HTML doivent avoir un ordre, un nom et un rôle logiques

Les instructions sont disponibles sous les commentaires : TODO: #6. Use Semantic HTML.

Identifier le problème

  1. Activez VoiceOver.
  2. Utilisez la navigation avec la touche Tabulation pour accéder à l'onglet Our Story (Notre histoire).
  3. Comme vous pouvez le constater, l'ordre suivi n'est pas séquentiel.
  4. Cliquez sur Purchase (Acheter).
  5. Notez que le bouton n'est pas reconnu comme tel.

69b5875f4d51d836.png

Transformer un élément <div> en <button>

Remplacez l'élément <div> personnalisé par un bouton Material :

src/app/shop/shop.component.html

<button mat-flat-button
  color="primary"
  class="purchase-button"
  (click)="fauxPurchase()">
  Purchase
</button>

Utiliser les éléments de titre dans l'ordre

Réorganisez le texte pour utiliser le HTML sémantique et appliquez un style à l'aide de la typographie Angular Material :

src/app/about/about.component.html

<h2>Who are we?</h2>
<p class="mat-subheading-2">Have you ever thought, "wow, I love dumplings"?</p>
<p class="right mat-subheading-1">Who hasn't.</p>
<p class="center mat-subheading-1">We took it one step further and created Dumpling Dumpling,</p>
<p class="center mat-subheading-1">double the dumpling, double the fun.</p>
<div class="spacer"></div>
<h2>How are we different?</h2>
<p class="mat-subheading-2">Handmade in San Francisco, California, we craft fully customizable dumplings. Glitter? Rainbows? Vegan? We do it all.</p>
<p class="right mat-subheading-2">This shop is concept only.</p>

Vérifier les modifications

Activez à nouveau votre lecteur d'écran, puis vérifiez les modifications. VoiceOver reconnaît désormais le bouton et lit le texte en respectant un ordre logique.

Audit de l'accessibilité :

  •  Le titre de chaque page est unique
  •  Les couleurs présentent un rapport de contraste suffisant
  •  Le HTML sémantique garantit une utilisation logique de l'application
  • 🛑 Les lecteurs d'écran ne peuvent pas sélectionner les cases à cocher imbriquées associées à des tailles
  • 🛑 Les lecteurs d'écran ne peuvent pas lire les valeurs de curseur
  • 🛑 Dans le sélecteur de couleur, le curseur du lecteur d'écran sort de la boîte de dialogue
  • 🛑 Les modifications, erreurs et notifications ne sont pas annoncées
  • 🛑 Le mode Contraste élevé n'est pas activé

Les commandes imbriquées représentent un schéma d'interaction complexe pour les services d'accessibilité. Considérons les sous-éléments de menu et les cases à cocher imbriquées. Comment indiquer à un utilisateur qu'il peut sélectionner un sous-groupe d'options ou accéder à un élément de menu parent ?

Rendez les menus et les commandes plus simples dans Angular de façon à créer des composants navigables. Pour cela, vous devez simplifier les commandes autant que possible. Ici, vous allez utiliser la zone de liste Angular Material pour créer un exemple de ce schéma d'interaction.

À la fin de cette section, votre application ne présentera plus le problème suivant :

  • 🛑 Les lecteurs d'écran ne peuvent pas sélectionner les cases à cocher imbriquées associées à des tailles

Les instructions sont disponibles sous les commentaires : TODO: #7. Create selectable controls with Angular Material.

Identifier le problème

Pour identifier ce problème, vous devrez activer le lecteur d'écran et tenter de cocher une case imbriquée.

  1. Activez VoiceOver.
  2. Sélectionnez différentes garnitures.
  3. Vous constatez que les cases à cocher parentes n'indiquent pas les cases enfants lorsque VoiceOver les lit. Ainsi, comment pouvez-vous savoir que la case Vegan n'est plus sélectionnée maintenant et que vous avez décoché la case Bok Choy ?

885a9bd0dbbd842a.png

Accessibilité dans Angular Material

Vous allez remplacer la case à cocher sémantique par la case à cocher Angular Material, qui intègre ce schéma d'interaction. Veuillez noter que remplacer un composant par son équivalent Material ne garantit pas son accessibilité. Comme n'importe quel composant, vous devrez le tester manuellement, car il est tout à fait possible d'implémenter un élément Material sans le rendre accessible.

Remplacer les cases à cocher par des cases à cocher Material

  1. Tout d'abord, ajoutez votre nouvelle liste de garnitures ainsi qu'une variable permettant d'enregistrer celles que vous avez sélectionnées :

src/app/shop/shop.component.ts

@Component(...)
export class ShopComponent implements OnInit {
  fillings: string[] = ['Bok Choy & Chili Crunch', 'Tofu & Mushroom', 'Chicken & Ginger', 'Impossible Meat & Spinach'];
  selectedFillings: string[] = [];

  fauxPurchase(): void {
    let flavor = '';
    this.selectedFillings.forEach(filling => {
      flavor = flavor + " " + filling
    })
  }
}
  1. Ajoutez un composant <mat-selection-list> pour remplacer ce regroupement de cases à cocher HTML :

src/app/shop/shop.component.html

<mat-selection-list [(ngModel)]="selectedFillings"
  aria-label="Dumpling fillings">
  <mat-list-option *ngFor="let flavor of fillings"
    [value]="flavor"
    color="primary">
    {{ flavor }}
  </mat-list-option>
</mat-selection-list>

Les commentaires TODO indiquent également où supprimer du Sass inutilisé dans src/app/shop/shop.component.scss pour épurer votre style.

Vérifier les modifications

Activez à nouveau votre lecteur d'écran, puis vérifiez les modifications. Vous pouvez désormais sélectionner et parcourir les cases à cocher de manière plus intuitive avec un lecteur d'écran.

e9d473e1e7949442.png

Audit de l'accessibilité :

  •  Le titre de chaque page est unique
  •  Les couleurs présentent un rapport de contraste suffisant
  •  Le HTML sémantique garantit une utilisation logique de l'application
  •  Les lecteurs d'écran peuvent accéder à toutes les commandes
  • 🛑 Les lecteurs d'écran ne peuvent pas lire les valeurs de curseur
  • 🛑 Dans le sélecteur de couleur, le curseur du lecteur d'écran sort de la boîte de dialogue
  • 🛑 Les modifications, erreurs et notifications ne sont pas annoncées
  • 🛑 Le mode Contraste élevé n'est pas activé

Vous avez modifié le HTML sémantique et les composants Material de votre application Angular, mais certains composants doivent disposer d'attributs spécifiques pour que les lecteurs d'écran puissent y accéder.

Les spécifications pour l'accessibilité des applications Web enrichies de l'initiative sur l'accessibilité du Web (WIA-ARIA ou ARIA) permettent de résoudre des problèmes impossibles à corriger à l'aide de HTML natif. Grâce à elles, vous pouvez indiquer des attributs modifiant la traduction d'un élément dans l'arborescence d'accessibilité.

À la fin de cette section, votre application ne présentera plus le problème suivant :

  • 🛑 Les lecteurs d'écran ne peuvent pas lire les valeurs de curseur

Les instructions sont disponibles sous les commentaires : TODO: #8. Provide control labels with ARIA.

Identifier le problème

Pour identifier ce problème, vous devrez activer votre lecteur d'écran et déplacer le curseur :

  1. Activez VoiceOver.
  2. Accédez au curseur permettant de choisir la quantité et modifiez la valeur.
  3. Vous pouvez constater qu'il manque le libellé de la valeur.

2d7dd751d8f835e6.png

Utiliser des attributs ARIA

Attribuez un libellé à la commande aria-label dans le composant <mat-slider> :

src/app/shop/shop.component.html

<mat-slider
  aria-label="Dumpling order quantity slider"
  id="quantity"
  name="quantity"
  color="primary"
  class="quantity-slider"
  [max]="13"
  [min]="1"
  [step]="1"
  [tickInterval]="1"
  thumbLabel
  [(ngModel)]="quantity">
</mat-slider>

Vérifier les modifications

Activez à nouveau votre lecteur d'écran, puis vérifiez les modifications. Vous pouvez désormais déplacer le curseur.

b21560426b30352c.png

Audit de l'accessibilité :

  •  Le titre de chaque page est unique
  •  Les couleurs présentent un rapport de contraste suffisant
  •  Le HTML sémantique garantit une utilisation logique de l'application
  •  Les lecteurs d'écran peuvent accéder à toutes les commandes
  •  Le curseur utilise des attributs ARIA afin de fournir un libellé
  • 🛑 Dans le sélecteur de couleur, le curseur du lecteur d'écran sort de la boîte de dialogue
  • 🛑 Les modifications, erreurs et notifications ne sont pas annoncées
  • 🛑 Le mode Contraste élevé n'est pas activé

Jusqu'à présent, vous avez employé des outils Angular intégrés pour résoudre des problèmes d'accessibilité courants. Étudions maintenant le module a11y du CDK, et découvrons comment l'utiliser pour résoudre des problèmes plus complexes et spécifiques à Angular.

À la fin de cette section, vous poursuivrez ce cours avec les outils du module a11y d'Angular.

Les instructions sont disponibles sous les commentaires : TODO: #9. Add the power of @angular/cdk/a11y.

Importer le module

Ajoutez le module à votre application :

src/app/app.module.ts

import { A11yModule } from '@angular/cdk/a11y';

@NgModule({
  declarations: [...],
  imports: [
    A11yModule
  ],
  providers: [...],
  bootstrap: [...]
})

À quoi '@angular/cdk/a11y' sert-il ?

Le module a11y fournit des outils destinés à améliorer l'accessibilité. Il est particulièrement utile pour les auteurs de composants.

Dans les sections suivantes, vous allez ajouter trois services courants : FocusTrap, LiveAnnouncer et HighContrast.

Pour en savoir plus sur l'ensemble des services fournis par @angular/cdk/a11y, consultez Accessibilité.

Lorsqu'une boîte de dialogue ou une fenêtre modale est ouverte, l'utilisateur n'interagit qu'à l'intérieur de celle-ci. Si le curseur peut en sortir, les contextes sont alors mélangés, et l'utilisateur risque de ne pas savoir où il se trouve sur la page.

Dans Angular, la directive cdkTrapFocus empêche la touche tab- de sortir d'un élément. Ainsi, vous assurez l'accessibilité des éléments comme les boîtes de dialogue modales, où les mouvements du curseur doivent être circonscrits.

À la fin de cette section, votre application ne présentera plus le problème suivant :

  • 🛑 Dans le sélecteur de couleur, le curseur du lecteur d'écran sort de la boîte de dialogue

Les instructions sont disponibles sous les commentaires : TODO: #10. Control focus with FocusTrap.

Identifier le problème

Pour identifier ce problème, vous devrez activer votre lecteur d'écran et ouvrir la boîte de dialogue du sélecteur de couleur.

  1. Activez VoiceOver.
  2. Modifiez la couleur à l'aide de la touche Tabulation.
  3. Observez l'ordre intuitif des déplacements du curseur et notez que celui-ci ne peut pas sortir du sélecteur de couleur.

2cad39ca0450a28e.png

Ajouter FocusTrap

cdkFocusTrap permet d'empêcher le curseur de sortir d'un composant personnalisé et de contrôler l'ordre de ses déplacements dans le composant. mat-dialog-content suffit à résoudre la plupart des problèmes en circonscrivant les déplacements du curseur dans la boîte de dialogue. Ajoutez l'attribut cdkFocusInitial pour faire en sorte que la zone de déplacement initiale du curseur soit la couleur de l'emballage des dumplings <mat-selection-list> au sein de la boîte de dialogue du sélecteur de couleur.

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.html

<mat-selection-list #colors aria-label="Dumpling wrapper color" multiple="false" cdkFocusInitial>
  ...
</mat-selection-list>

Vérifier les modifications

Activez à nouveau votre lecteur d'écran, puis vérifiez les modifications. Lorsque la boîte de dialogue s'ouvre, le curseur se trouve désormais sur Change Color (Modifier la couleur).

Audit de l'accessibilité :

  •  Le titre de chaque page est unique
  •  Les couleurs présentent un rapport de contraste suffisant
  •  Le HTML sémantique garantit une utilisation logique de l'application
  •  Les lecteurs d'écran peuvent accéder à toutes les commandes
  •  Le curseur utilise des attributs ARIA afin de fournir un libellé
  •  Les déplacements du curseur sont circonscrits au sélecteur de couleur
  • 🛑 Les modifications, erreurs et notifications ne sont pas annoncées
  • 🛑 Le mode Contraste élevé n'est pas activé

Lorsqu'un élément de la page est modifié, les lecteurs d'écran doivent en être informés. Imaginez que vous tentez d'envoyer un formulaire ou de finaliser un achat. Une erreur se produit et empêche l'envoi du formulaire, mais vous n'en êtes pas informé. C'est un vrai problème.

LiveAnnouncer vous permet d'annoncer des messages aux utilisateurs de lecteurs d'écran par le biais d'une zone live aria. Ainsi, vous êtes certain que les lecteurs d'écran sont informés des notifications et des modifications apportées à la page en ligne. Pour plus d'informations sur les zones live aria, consultez WAI-ARIA du W3C. Dans Angular, nous vous recommandons d'utiliser LiveAnnouncer en tant que service plutôt que des attributs aria-live, car il est plus facile de tester cette solution.

À la fin de cette section, votre application ne présentera plus le problème suivant :

  • 🛑 Les modifications, erreurs et notifications ne sont pas annoncées

Les instructions sont disponibles sous les commentaires : TODO: #11. Announce changes with LiveAnnouncer.

Identifier le problème

Pour identifier ce problème, vous devrez activer votre lecteur d'écran, puis sélectionner Purchase (Acheter) sans remplir les champs du formulaire :

  1. Activez VoiceOver.
  2. Modifiez la couleur et faites un achat fictif à l'aide de la touche Tabulation.
  3. Notez que le lecteur d'écran ne vous a pas informé de la couleur choisie lorsque vous avez quitté la boîte de dialogue et qu'il n'a pas lu votre achat.

8ec0de4079feaae7.png

Ajouter la fonctionnalité LiveAnnouncer au code

Ajoutez LiveAnnouncer, puis annoncez la couleur sélectionnée et l'achat fictif en tant que chaîne. Dans une implémentation réelle, la chaîne est susceptible d'être lue lorsque vous accédez à un système de paiement tiers ou en cas de problème avec un formulaire.

  1. Incluez une annonce lorsqu'une couleur est sélectionnée :

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ColorPickerDialogComponent implements OnInit {
  constructor(
    public dialogRef: MatDialogRef<ColorPickerDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: ColorDialogData,
    private liveAnnouncer: LiveAnnouncer) { }

  public changeColor(color: string): void {
    this.liveAnnouncer.announce(`Select color: ${color}`);
    this.dialogRef.close();
  }
}
  1. Incluez une annonce lorsqu'un achat fictif est effectué :

src/app/shop/shop.component.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ShopComponent implements OnInit {

  constructor(private liveAnnouncer: LiveAnnouncer) { }

  fauxPurchase(): void {
    let flavor = '...';
    const fakePurchase = `Purchase ${this.quantity} ${flavor}dumplings in the color ${this.color}!`;

    this.liveAnnouncer.announce(fakePurchase);
  }
}

Vérifier les modifications

Activez à nouveau votre lecteur d'écran, puis vérifiez les modifications. Vous voici désormais informé des erreurs qui se produisent !

Audit de l'accessibilité :

  •  Le titre de chaque page est unique
  •  Les couleurs présentent un rapport de contraste suffisant
  •  Le HTML sémantique garantit une utilisation logique de l'application
  •  Les lecteurs d'écran peuvent accéder à toutes les commandes
  •  Le curseur utilise des attributs ARIA afin de fournir un libellé
  •  Les déplacements du curseur sont circonscrits au sélecteur de couleur
  •  Les modifications, les erreurs et les notifications sont annoncées
  • 🛑 Le mode Contraste élevé n'est pas activé

Microsoft Windows propose une fonctionnalité d'accessibilité appelée "mode Contraste élevé". Ce mode change l'apparence de toutes les applications (y compris les applications Web) afin d'augmenter considérablement le contraste. Dans Angular, vous devez respecter les préférences de l'utilisateur pour votre application.

HighContrastModeDetector vous aide de déterminer si l'environnement d'un navigateur est en mode Contraste élevé.

Internet Explorer, Microsoft Edge et Firefox sont compatibles avec le mode Contraste élevé de Windows, mais Google Chrome ne l'est pas. En effet, ce service ne détecte pas le mode Contraste élevé tel qu'il est ajouté par l'extension Contraste élevé pour le navigateur Chrome.

À la fin de cette section, votre application ne présentera plus le problème suivant :

  • 🛑 Le mode Contraste élevé n'est pas activé

Les instructions sont disponibles sous les commentaires : TODO: #12. Enable HighContrast mode.

Identifier le problème

Pour identifier ce problème, vous devrez ouvrir votre application dans Internet Explorer, Microsoft Edge ou Firefox, activer le mode Contraste élevé, puis observer l'absence de modification :

  1. Ouvrez votre application dans Internet Explorer, Microsoft Edge ou Firefox.
  2. Activez le mode Contraste élevé.
  3. Notez que l'application demeure inchangée.

Permettre l'utilisation du mode Contraste élevé

Dans styles.scss, utilisez le mixin cdk-high-contrast fourni dans @angular/cdk/a11y pour ajouter un contour aux boutons lorsque le mode Contraste élevé est activé :

src/app/shop/shop.component.scss

@import '~@angular/cdk/a11y';

.purchase-button {
    border-radius: 5px;
    background-color: mat.get-color-from-palette(mat.$pink-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$pink-palette, 50);
    }
}

:host-context(.dark-theme) {
  .purchase-button {
    background-color: mat.get-color-from-palette(mat.$light-green-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$light-green-palette, 50);
    }
  }
}

Vérifier les modifications

Actualisez votre application et confirmez les modifications. Vous avez ajouté un contour aux boutons en mode Contraste élevé.

83c10ae8bd841e2e.png cb49574f76cdb85c.png

Audit de l'accessibilité :

  •  Le titre de chaque page est unique
  •  Les couleurs présentent un rapport de contraste suffisant
  •  Le HTML sémantique garantit une utilisation logique de l'application
  •  Les lecteurs d'écran peuvent accéder à toutes les commandes
  •  Le curseur utilise des attributs ARIA afin de fournir un libellé
  •  Les déplacements du curseur sont circonscrits au sélecteur de couleur
  •  Les modifications, les erreurs et les notifications sont annoncées
  •  Le mode contraste élevé est activé

Félicitations, vous avez résolu les problèmes d'accessibilité courants dans votre application Angular ! 🎉

Pour afficher toutes les solutions, accédez à la branche main.

147ed8c9c57b3a2.png 2044559004149c85.png 4d594c26474fe97.png

Vous connaissez désormais les principales étapes nécessaires pour résoudre huit erreurs courantes d'accessibilité dans votre application Angular.

En savoir plus

Découvrez ces ateliers de programmation :

Consultez les ressources suivantes :