Crea app Angular più accessibili

1. Prima di iniziare

Logo Angular nero

L'accessibilità è una parte fondamentale dello sviluppo web, in quanto garantisce che gli utenti possano percepire, comprendere, navigare e interagire con le app. Infatti, 1 adulto su 4 negli Stati Uniti ha una disabilità che influisce sulle sue principali attività quotidiane. A livello mondiale, circa il 15% della popolazione, ovvero più di 1 miliardo di persone, ha qualche forma di disabilità, mentre circa il 2-4% ha difficoltà significative.

Le condizioni comuni che influiscono sull'utilizzo del web da parte di una persona includono cecità o ipovisione, sordità o problemi di udito, capacità motorie limitate, disabilità cognitive e daltonismo. Questo è solo un elenco parziale.

In questo corso, a11y è l'abbreviazione di accessibilità. Tieni presente che la a è seguita da 11 caratteri e da una y.

Per un'introduzione approfondita ai problemi e alle tecniche per la progettazione di app accessibili, vedi Accessibilità.

Cosa creerai

  • Utilizza le best practice e le tecniche integrate per risolvere i problemi comuni di accessibilità web in un'app Angular demo Dumpling Shop
  • Rispetta tutte le linee guida per l'accessibilità, WCAG 2.0 e ARIA 1.2 e supera i controlli di accessibilità di axe e Lighthouse.

Sito web del negozio Dumpling Time con tema rosa e rosso Sito web del negozio Dumpling Time con tema viola e verde

Cosa imparerai a fare

Scopri otto problemi di accessibilità comuni nelle app Angular che interessano gli utenti, come identificarli e come risolverli. Più nello specifico, dovrai:

  • Utilizza gli Strumenti per sviluppatori di Google Chrome, Lighthouse e axe per controllare l'accessibilità della tua app
  • Risolvere i problemi delle app a pagina singola (SPA) con titoli di pagina univoci
  • Risolvere i problemi di contrasto dei colori per gli utenti ipovedenti
  • Utilizzare codice HTML semantico per garantire che gli screen reader navighino correttamente nella pagina
  • Utilizza Angular Material e separa i controlli per assicurarti che gli screen reader possano accedere a tutti i controlli
  • Aggiungere il supporto ARIA per gli screen reader
  • Importa e utilizza il pacchetto a11y dell'Angular CDK
  • Utilizzare FocusTrap per la navigazione dello screen reader dei componenti personalizzati
  • Annunciare le notifiche con CDK LiveAnnouncer
  • Rilevare gli utenti con la modalità ad alto contrasto e implementare i temi ad alto contrasto

Che cosa ti serve

2. Configurazione

Ottieni il codice

Tutto ciò che ti serve per questo progetto si trova in un repository GitHub. Per iniziare, clona il codice e aprilo nel tuo ambiente di sviluppo preferito.

Clona il repository e pubblica l'app

VSCode o un IDE locale sono il metodo consigliato per completare questo codelab.

  1. Apri una nuova scheda del browser e vai a https://github.com/googlecodelabs/angular-accessibility.
  2. Crea un fork e clona il repository, quindi cd angular-accessibility/ nel repository.
  3. Dai un'occhiata al ramo del codice di avvio git checkout get-started.
  4. Apri il codice in VSCode o nell'IDE che preferisci.
  5. Esegui npm install per installare le dipendenze necessarie per eseguire il server.
  6. Esegui ng serve per eseguire il server.
  7. Apri una scheda del browser all'indirizzo http://localhost:4200.

3. Stabilire una base di riferimento

Qual è il tuo punto di partenza?

Il punto di partenza è un'app di base per ristoranti progettata per questo codelab. Il codice è stato semplificato per mostrare i concetti di questo codelab e ha poche funzionalità.

Sito web del negozio Dumpling Time con tema viola e verde

Esplora la demo

Per iniziare, esamina le tre funzionalità dell'app:

  1. Utilizza la barra di navigazione per visualizzare i percorsi Il nostro negozio, La nostra storia e Dove trovarci e visualizzare i dettagli dell'azienda di ravioli.
  2. Cambia i temi per attivare e disattivare la modalità Buio.
  3. Personalizza i ripieni, la quantità e il colore dei ravioli dell'ordine.
  4. Seleziona Acquisto per registrare l'ordine personalizzato nella console.

Utilizzare Angular per risolvere i problemi comuni di accessibilità web

In questo codelab, ti concentrerai sull'accessibilità delle funzionalità esistenti di questa app. Inizierai identificando i problemi di accessibilità nella tua app, quindi trasformerai il 🛑 in un ✅ implementando una soluzione.

Come fai a sapere cosa correggere?

Inizia ogni esempio riconoscendo il problema di accessibilità utilizzando una combinazione di test manuali e automatici.

Nello stato attuale del web, il test manuale dell'accessibilità è obbligatorio.

Esistono strumenti che possono identificare i problemi di accessibilità, ma nessuno strumento può certificare che un'app sia completamente accessibile. I test manuali ti consentono di testare un'ampia gamma di concetti di accessibilità, tra cui l'ordine logico dei contenuti e la parità delle funzionalità.

Test manuale

Per testare manualmente l'accessibilità in questo corso, attiva lo screen reader integrato del computer e naviga nell'app con la navigazione da tastiera. Per ulteriori informazioni, consulta Semantica e screen reader.

Esercitati attivando lo screen reader e navigando sullo schermo.

Puoi utilizzare VoiceOver integrato in macOS. Fai clic su Preferenze di sistema > Accessibilità > VoiceOver > Attiva VoiceOver per abilitarlo. Per attivare/disattivare VoiceOver, premi rapidamente tre volte Touch ID mentre tieni premuto il tasto Command.

In questo corso, testerai principalmente i problemi manualmente e utilizzerai strumenti automatizzati per verificare funzionalità specifiche automatizzabili.

Test automatici

Utilizzi anche alcuni strumenti di sviluppo per automatizzare e controllare la tua app. Questi strumenti ti consentono di verificare elementi come la presenza di testo alternativo in un'immagine o il rapporto di contrasto di un colore del testo. Puoi considerare questi strumenti come dei linter: possono riconoscere la presenza del testo alternativo, ma devi controllare manualmente che il contenuto sia logico e fornisca valore.

Lighthouse e Strumenti per sviluppatori di Chrome

  1. Apri gli Strumenti per sviluppatori di Chrome.
  2. Seleziona la scheda Lighthouse e la casella di controllo Accessibilità.
  3. Fai clic su Genera report per eseguire un controllo Lighthouse per l'accessibilità.

Scheda di esempio di Lighthouse con il pulsante per generare il report in una scheda di Chrome DevTools

Axe

  1. Installa l'estensione axe DevTools. Potresti dover riavviare il browser per visualizzare l'estensione.
  2. Apri gli Strumenti per sviluppatori di Chrome.
  3. Seleziona la scheda axe DevTools e poi Scansiona tutta la pagina per eseguire una scansione axe DevTools.

Analisi tramite lint

Puoi utilizzare le regole ESLint di Angular per eseguire il linting del codice per gli attributi di accessibilità automatizzabili.

In eslint.json, aggiungi quanto segue, che si applica all'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

Per maggiori informazioni, consulta le ultime regole ESLint su GitHub.

Il tuo punto di partenza

Utilizzando i nuovi metodi di test, puoi identificare i seguenti problemi nella tua app utilizzando i controlli Lighthouse e axe e VoiceOver manuale:

Controllo Lighthouse di Chrome DevTools con un punteggio di 82

Controllo accessibilità:

  • 🛑 Tutte le pagine hanno lo stesso titolo
  • 🛑 Gli elementi devono avere un contrasto cromatico sufficiente
  • 🛑 L'HTML deve avere ordine, nome e ruolo logici
  • 🛑 Le caselle di controllo nidificate non sono selezionabili per gli screen reader
  • 🛑 Lo screen reader non legge i valori del cursore
  • 🛑 Lo stato attivo dello screen reader nel selettore del colore esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità ad alto contrasto non è attivata

4. Definire titoli di pagina univoci

Fornire titoli di pagina unici e concisi aiuta gli utenti che utilizzano servizi di accessibilità a comprendere rapidamente i contenuti e lo scopo di una pagina web. I titoli delle pagine sono fondamentali per gli utenti con disabilità visive perché sono il primo elemento della pagina annunciato dal software di lettura dello schermo.

Angular è un'app a una sola pagina e, di conseguenza, la maggior parte delle transizioni, ad esempio il passaggio a una nuova pagina, non comporta un ricaricamento della pagina. Fino a poco tempo fa, ciò significava che ogni pagina aveva un titolo identico e non forniva alcun valore per comprendere i contenuti o lo scopo della pagina.

In Angular v14, il router ha aggiunto un metodo integrato per definire titoli di pagina unici pronti all'uso. In questo modo, gli sviluppatori possono seguire le best practice per i titoli delle pagine in modo più semplice.

Al termine di questa sezione, la tua app supererà il seguente audit:

  • 🛑 Tutte le pagine hanno lo stesso titolo

Puoi trovare ciascuno di questi passaggi sotto il commento: TODO: #4. Define unique page titles.

Identificare il problema

Per identificare il problema, attiva lo screen reader e naviga tra le schede Il nostro negozio, La nostra storia e Dove trovarci per visualizzare i titoli delle pagine:

  1. Attiva VoiceOver.
  2. Utilizza la navigazione a schede per spostarti tra le pagine.
  3. Verifica che il titolo della pagina sia sempre a11y in Angular.

Si tratta di un problema perché il titolo della pagina deve essere univoco, in modo che un utente possa capire rapidamente di cosa tratta la pagina senza doverla consultare.

Browser Chrome con tre schede aperte con lo stesso titolo della pagina: "a11y in Angular"

Aggiungere titoli di pagina significativi

Se una pagina o una visualizzazione cambia, devi gestire correttamente il titolo della pagina. Per risolvere il problema, utilizza la proprietà Router.title integrata di Angular per definire titoli univoci per ogni pagina.

  1. Aggiungi un titolo univoco a ciascuno dei tre itinerari definiti:

src/app/app-routing.module.ts

const routes: Routes = [
  { path: 'shop', component: ShopComponent, title: 'Our Shop – a11y in Angular' },
  { path: 'about', component: AboutComponent, title: 'Our Story - a11y in Angular' },
  { path: 'locate', component: LocationComponent, title: 'Find Us - a11y in Angular' },
  { path: '',   redirectTo: '/shop', pathMatch: 'full' },
  { path: '**', component: ShopComponent },
];

In questo modo, Router's Title Service verrà importato e utilizzato automaticamente per gestire la modifica del titolo della pagina nella navigazione in modo che corrisponda alla proprietà del titolo definita nelle nostre route. Puoi anche gestire titoli di pagina più complessi utilizzando un TitleStrategy personalizzato.

Verifica le modifiche

Attiva di nuovo lo screen reader e verifica le modifiche. Ora le pagine dovrebbero avere titoli univoci.

Browser Chrome con tre schede aperte con titoli di pagina unici: "Our Shop - a11y in Angular", "Our Story - a11y in Angular", "Find Us - a11y in Angular"

Controllo accessibilità:

  • Tutte le pagine hanno titoli univoci
  • 🛑 Gli elementi devono avere un contrasto cromatico sufficiente
  • 🛑 L'HTML deve avere ordine, nome e ruolo logici
  • 🛑 Le caselle di controllo nidificate non sono selezionabili per gli screen reader
  • 🛑 Lo screen reader non legge i valori del cursore
  • 🛑 Lo stato attivo dello screen reader nel selettore del colore esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità ad alto contrasto non è attivata

5. Garantire un contrasto cromatico adeguato

Il tuo design potrebbe sembrare fantastico, ma non lo è se le persone con disabilità visive come il daltonismo non riescono a leggere i tuoi contenuti. Le linee guida per l'accessibilità dei contenuti web (WCAG 2.0) definiscono una serie di rapporti di contrasto del colore, che garantiscono l'accessibilità dei contenuti. In Angular e sul web, puoi definire tavolozze di colori che garantiscano che i tuoi componenti soddisfino questi standard e siano visibili agli utenti con problemi di vista e daltonismo.

Al termine di questa sezione, la tua app supererà il seguente audit:

  • 🛑 Gli elementi devono avere un contrasto cromatico sufficiente

Puoi trovare ciascuno di questi passaggi sotto i commenti: TODO: #5. Ensure adequate color contrast.

Utilizzare gli Strumenti per sviluppatori di Chrome per identificare i problemi di basso contrasto

Per identificare questo problema, utilizza gli Strumenti per sviluppatori di Chrome per ispezionare gli elementi della tua app.

  1. Utilizza lo strumento di ispezione per visualizzare i pulsanti delle icone del menu. Puoi notare che il contrasto è 1,85, molto al di sotto dei requisiti WCAG.

Chrome DevTools ispeziona l'elemento di un pulsante Home con contrasto basso

  1. Esegui il controllo dell'accessibilità in Lighthouse o la scansione di axe per visualizzare questi problemi relativi al rapporto di contrasto.

Risultati dell'audit Lighthouse di Chrome DevTools con errore: "Il rapporto di contrasto tra i colori di sfondo e primo piano non è sufficiente"

Modificare il colore del tema Material

La combinazione di colori dei componenti è definita nel tema Material personalizzato. Aggiorni il valore del tema in modo che rispetti le linee guida sul rapporto di contrasto cromatico.

Aggiorna il tema Material per utilizzare un colore del testo più scuro, aumentando il rapporto di contrasto delle icone:

src/styles.scss

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

Puoi anche utilizzare gli strumenti per sviluppatori di Chrome integrati per l'accessibilità per trovare un colore che soddisfi gli standard o aggiornare i singoli valori di colore in Sass.

Verifica le modifiche

Ispeziona di nuovo gli elementi e verifica le modifiche. Il tema dovrebbe ora avere rapporti di contrasto cromatico sufficienti.

Chrome DevTools ispeziona l'elemento di un pulsante Home con contrasto sufficiente

Controllo accessibilità

  • Tutte le pagine hanno titoli univoci
  • I colori hanno un rapporto di contrasto sufficiente
  • 🛑 L'HTML deve avere ordine, nome e ruolo logici
  • 🛑 Le caselle di controllo nidificate non sono selezionabili per gli screen reader
  • 🛑 Lo screen reader non legge i valori del cursore
  • 🛑 Lo stato attivo dello screen reader nel selettore del colore esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità ad alto contrasto non è attivata

6. Utilizzare l'HTML semantico

Gli elementi HTML nativi acquisiscono una serie di pattern di interazione standard importanti per l'accessibilità. Sebbene un paragrafo possa essere stilizzato come uno span e un div possa essere stilizzato come un pulsante, l'elemento HTML semantico garantisce che gli screen reader e la navigazione da tastiera comprendano le interazioni e i controlli del tuo HTML.

Quando crei componenti Angular, devi riutilizzare direttamente questi elementi nativi, se possibile, anziché reimplementare comportamenti ben supportati. In questo modo, la pagina ha una buona struttura dei contenuti e un flusso naturale, e la scheda è in un ordine logico per aiutare gli utenti a navigare nel sito web utilizzando la tastiera in modo efficace.

Al termine di questa sezione, la tua app supererà il seguente audit:

  • 🛑 L'HTML deve avere ordine, nome e ruolo logici

Puoi trovare ciascuno di questi passaggi sotto i commenti: TODO: #6. Use Semantic HTML.

Identificare il problema

  1. Attiva VoiceOver.
  2. Utilizza la navigazione con il tasto Tab per passare alla scheda La nostra storia.
  3. Nota che l'ordine delle schede non è sequenziale.
  4. Fai clic su Purchas.
  5. Nota che il pulsante non viene riconosciuto come tale.

Risultati del controllo Lighthouse di Chrome DevTools con errore: gli elementi di intestazione non sono in ordine decrescente sequenziale. Le intestazioni nell'ordine corretto che non saltano livelli descrivono la struttura semantica della pagina, facilitando la navigazione e la comprensione quando vengono usate tecnologie per la disabilità. Ulteriori informazioni.

Modifica di un tag <div> in un tag <button>

Sostituisci il tag <div> personalizzato con un pulsante Material:

src/app/shop/shop.component.html

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

Utilizzare gli elementi di intestazione in sequenza

Riordina il testo per utilizzare l'HTML semantico e applica lo stile utilizzando la tipografia di 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>

Verifica le modifiche

Attiva di nuovo lo screen reader e verifica le modifiche. VoiceOver ora riconosce il pulsante e il testo viene letto in un ordine logico.

Controllo accessibilità:

  • Tutte le pagine hanno titoli univoci
  • I colori hanno un rapporto di contrasto sufficiente
  • L'HTML semantico garantisce un'interazione logica
  • 🛑 Le caselle di controllo nidificate non sono selezionabili per gli screen reader
  • 🛑 Lo screen reader non legge i valori del cursore
  • 🛑 Lo stato attivo dello screen reader nel selettore del colore esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità ad alto contrasto non è attivata

7. Creare controlli selezionabili con Angular Material

Un modello di interazione complicato per i servizi di accessibilità è rappresentato dai controlli nidificati. Pensa a voci secondarie del menu o a caselle di controllo nidificate. Come si indica a un utente che può selezionare un sottogruppo di opzioni o passare a una voce di menu principale?

In Angular, semplifica i menu e i controlli per creare componenti navigabili semplificando il più possibile i controlli. In questo esempio, utilizzi la casella di riepilogo di Angular Material per creare un esempio di questo pattern di interazione.

Al termine di questa sezione, la tua app supererà il seguente audit:

  • 🛑 Le caselle di controllo nidificate non sono selezionabili per gli screen reader

Puoi trovare ciascuno di questi passaggi sotto i commenti: TODO: #7. Create selectable controls with Angular Material.

Identificare il problema

Per identificare questo problema, attiveremo il nostro screen reader e tenteremo di selezionare una casella di controllo nidificata.

  1. Attiva VoiceOver.
  2. Seleziona gusti di ripieno diversi.
  3. Tieni presente che le caselle di controllo per i genitori non specificano i figli quando vengono lette da VoiceOver. Come fai a sapere che la casella di controllo Vegano è deselezionata ora che hai deselezionato la casella di controllo Bok Choy?

Menu con caselle di controllo per i ripieni: ripieni vegani di tofu e bok choy e carne di shitake, pollo e carne Impossible

Accessibilità in Angular Material

Sostituisci la casella di controllo semantica con la casella di controllo Angular Material, che contiene la conoscenza integrata di questo pattern di interazione. È importante notare che la sostituzione dei componenti con Material non garantisce l'accessibilità. Come per qualsiasi altro componente, devi eseguire il test manualmente perché esistono molti modi per implementare Material in modo inaccessibile.

Sostituire le caselle di controllo con le caselle di controllo Material

  1. Innanzitutto, aggiungi il nuovo elenco di ripieni e una variabile per memorizzare i gusti di ripieno selezionati:

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. Aggiungi un <mat-selection-list> per sostituire questo raggruppamento disordinato di caselle di controllo 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>

I commenti TODO mostrano anche dove puoi rimuovere alcuni stili Sass inutilizzati in src/app/shop/shop.component.scss per pulire lo stile.

Verifica le modifiche

Attiva di nuovo lo screen reader e verifica le modifiche. Ora le caselle di controllo sono selezionabili e la navigazione è più intuitiva con uno screen reader.

Menu della casella di controllo dei ripieni con le voci: Ripieni Bok Choy, Tofu croccante al peperoncino, Pollo e funghi, Impossible Meat allo zenzero e Spinaci Quantità

Controllo accessibilità:

  • Tutte le pagine hanno titoli univoci
  • I colori hanno un rapporto di contrasto sufficiente
  • L'HTML semantico garantisce un'interazione logica
  • Tutti i controlli sono raggiungibili dagli screen reader
  • 🛑 Lo screen reader non legge i valori del cursore
  • 🛑 Lo stato attivo dello screen reader nel selettore del colore esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità ad alto contrasto non è attivata

8. Fornire etichette di controllo con ARIA

Hai modificato l'HTML semantico e i componenti Material della tua app Angular, ma alcuni componenti richiedono attributi specifici per essere navigati completamente dagli screen reader.

La specifica Accessible Rich Internet Applications della Web Accessibility Initiative (WAI-ARIA o ARIA) aiuta a risolvere i problemi che non possono essere gestiti con HTML nativo. Consente di specificare gli attributi che modificano il modo in cui un elemento viene tradotto nell'albero di accessibilità.

Al termine di questa sezione, la tua app supererà il seguente audit:

  • 🛑 Lo screen reader non legge i valori del cursore

Puoi trovare ciascuno di questi passaggi sotto i commenti: TODO: #8. Provide control labels with ARIA.

Identificare il problema

Per identificare questo problema, attiva lo screen reader e sposta il cursore:

  1. Attiva VoiceOver.
  2. Vai al cursore della quantità e modifica il valore.
  3. Nota che l'etichetta del valore non è presente.

Risultati del controllo Lighthouse di Chrome DevTools con errore:  I campi di immissione ARIA non hanno nomi accessibili Quando un campo di immissione non ha un nome accessibile, gli screen reader lo descrivono con un nome generico, rendendolo inutilizzabile per gli utenti che si affidano agli screen reader. Ulteriori informazioni.

Utilizzare gli attributi ARIA

Controllo delle etichette tramite aria-label fino a <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>

Verifica le modifiche

Attiva di nuovo lo screen reader e verifica le modifiche. Ora puoi spostare il cursore.

Controllo Lighthouse di Chrome DevTools con controllo superato per i controlli ARIA dello screen reader.

Controllo accessibilità:

  • Tutte le pagine hanno titoli univoci
  • I colori hanno un rapporto di contrasto sufficiente
  • L'HTML semantico garantisce un'interazione logica
  • Tutti i controlli sono raggiungibili dagli screen reader
  • Il cursore utilizza gli attributi ARIA per fornire un'etichetta
  • 🛑 Lo stato attivo dello screen reader nel selettore del colore esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità ad alto contrasto non è attivata

9. Aggiungi la potenza di @angular/cdk/a11y

Finora, ti sei affidato agli strumenti Angular integrati per risolvere i problemi comuni di accessibilità. Ora esaminiamo il modulo a11y del CDK e come può aiutarci a risolvere problemi più complessi e specifici di Angular.

Al termine di questa sezione, continuerai il corso con gli strumenti del modulo a11y di Angular.

Puoi trovare questi passaggi nel commento: TODO: #9. Add the power of @angular/cdk/a11y.

Importa il modulo

Aggiungi il modulo alla tua app:

src/app/app.module.ts

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

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

Che cosa fa '@angular/cdk/a11y' ?

Il modulo a11y fornisce una serie di strumenti per migliorare l'accessibilità ed è particolarmente utile per gli autori di componenti.

Nelle sezioni seguenti, aggiungi tre servizi comuni: FocusTrap, LiveAnnouncer e HighContrast.

Per saperne di più su tutti gli altri servizi forniti da @angular/cdk/a11y, consulta la sezione Accessibilità.

10. Controllare lo stato attivo con FocusTrap

Quando una finestra di dialogo o modale è aperta, un utente interagisce solo al suo interno. Consentire al focus di uscire dalla finestra di dialogo mescola i contesti e crea uno stato in cui l'utente non sa in quale punto della pagina si trova.

In Angular, la direttiva cdkTrapFocus blocca lo stato attivo del tasto tab- all'interno di un elemento. Questa proprietà è pensata per essere utilizzata per creare un'esperienza accessibile per componenti come le finestre di dialogo modali, in cui lo stato attivo deve essere vincolato.

Al termine di questa sezione, la tua app supererà il seguente audit:

  • 🛑 Lo stato attivo dello screen reader nel selettore del colore esce dalla finestra di dialogo

Puoi trovare questi passaggi sotto i commenti: TODO: #10. Control focus with FocusTrap.

Identificare il problema

Per identificare il problema, attiva lo screen reader e apri la finestra di dialogo del selettore di colori.

  1. Attiva VoiceOver.
  2. Utilizza la navigazione a schede per modificare il colore.
  3. Controlla l'ordine di messa a fuoco intuitivo e il blocco della messa a fuoco nel selettore di colori.

Sito web del negozio Dumpling Time con tema viola e verde e finestra di dialogo aperta per selezionare il colore dell&#39;involucro dei ravioli

Aggiungi FocusTrap

cdkFocusTrap può essere utilizzato per intercettare e controllare l'ordine di messa a fuoco nei componenti personalizzati. L'utilizzo di mat-dialog-content è sufficiente per risolvere la maggior parte dei problemi bloccando lo stato attivo in una finestra di dialogo. Aggiungi l'attributo cdkFocusInitial per definire la regione di messa a fuoco iniziale sul colore dell'involucro del dumpling <mat-selection-list> all'interno della finestra di dialogo del selettore colori.

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>

Verifica le modifiche

Attiva di nuovo lo screen reader e verifica le modifiche. Lo stato attivo è ora inizialmente impostato su Cambia colore nella finestra di dialogo.

Controllo accessibilità:

  • Tutte le pagine hanno titoli univoci
  • I colori hanno un rapporto di contrasto sufficiente
  • L'HTML semantico garantisce un'interazione logica
  • Tutti i controlli sono raggiungibili dagli screen reader
  • Il cursore utilizza gli attributi ARIA per fornire un'etichetta
  • Il selettore colori ha un corretto intrappolamento della messa a fuoco
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità ad alto contrasto non è attivata

11. Annunciare le modifiche con LiveAnnouncer

I lettori di schermo devono ricevere una notifica quando qualcosa nella pagina cambia. Immagina di provare a inviare un modulo o completare un acquisto e di non sapere che è comparso un errore che impedisce l'invio del modulo. Che frustrazione!

LiveAnnouncer viene utilizzato per annunciare i messaggi agli utenti di screen reader utilizzando una regione aria-live per garantire che gli screen reader vengano informati delle notifiche e delle modifiche alle pagine live. Per saperne di più sulle regioni aria-live, consulta WAI-ARIA di W3C. In Angular, chiamare LiveAnnouncer come servizio è una soluzione più testabile rispetto agli attributi aria-live.

Al termine di questa sezione, la tua app supererà il seguente audit:

  • 🛑 Modifiche, errori e notifiche non vengono annunciati

Puoi trovare questi passaggi sotto i commenti: TODO: #11. Announce changes with LiveAnnouncer.

Identificare il problema

Per identificare questo problema, attiva lo screen reader e seleziona Acquisto senza compilare i campi del modulo:

  1. Attiva VoiceOver.
  2. Utilizza la navigazione a schede per cambiare il colore ed effettuare un acquisto simulato.
  3. Tieni presente che non viene indicata la selezione del colore quando esci dalla finestra di dialogo e l'acquisto non viene letto.

Sito web del negozio Dumpling Time con tema rosa e rosso e finestra di dialogo aperta per selezionare il colore dell&#39;involucro dei ravioli

Aggiungere LiveAnnouncer al codice

Aggiungi LiveAnnouncer e annuncia sia la selezione del colore sia l'acquisto fittizio come stringa. In un'implementazione reale, questo messaggio potrebbe essere letto quando navighi in un sistema di pagamento di terze parti o per errori del modulo.

  1. Aggiungi un annuncio quando viene selezionato un colore:

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. Aggiungi un annuncio quando viene effettuato un acquisto falso:

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

Verifica le modifiche

Attiva di nuovo lo screen reader e verifica le modifiche. Ora riceverai una notifica degli errori.

Controllo accessibilità:

  • Tutte le pagine hanno titoli univoci
  • I colori hanno un rapporto di contrasto sufficiente
  • L'HTML semantico garantisce un'interazione logica
  • Tutti i controlli sono raggiungibili dagli screen reader
  • Il cursore utilizza gli attributi ARIA per fornire un'etichetta
  • Il selettore colori ha un corretto intrappolamento della messa a fuoco
  • Vengono annunciati modifiche, errori e notifiche
  • 🛑 La modalità ad alto contrasto non è attivata

12. Attivare la modalità ad alto contrasto

Microsoft Windows supporta una funzionalità di accessibilità chiamata modalità ad alto contrasto. Questa modalità modifica l'aspetto di tutte le app, incluse le app web, per aumentare notevolmente il contrasto. In Angular, vuoi rispettare le preferenze di un utente nella tua app.

HighContrastModeDetector consente di determinare se il browser si trova attualmente in un ambiente in modalità ad alto contrasto.

Internet Explorer, Microsoft Edge e Firefox supportano questa modalità. Google Chrome non supporta la modalità di contrasto elevato di Windows. Questo servizio non rileva la modalità ad alto contrasto aggiunta dall'estensione del browser Contrasto elevato di Chrome.

Al termine di questa sezione, la tua app supererà il seguente audit:

  • 🛑 La modalità ad alto contrasto non è attivata

Puoi trovare questi passaggi sotto i commenti: TODO: #12. Enable HighContrast mode.

Identificare il problema

Per identificare questo problema, apri l'app in Internet Explorer, Microsoft Edge o Firefox, attiva la modalità ad alto contrasto e osserva la mancanza di modifiche:

  1. Apri l'app in Internet Explorer, Microsoft Edge o Firefox.
  2. Attiva la modalità ad alto contrasto.
  3. Nota che l'applicazione è rimasta invariata.

Aggiungere il supporto per la modalità ad alto contrasto

In styles.scss, utilizza il mixin cdk-high-contrast fornito in @angular/cdk/a11y per aggiungere un contorno ai pulsanti in modalità Alto contrasto:

src/app/shop/shop.component.scss

@use '@angular/cdk';

.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);
    }
  }
}

Verifica le modifiche

Aggiorna l'app e verifica le modifiche. Hai aggiunto un contorno al pulsante in modalità ad alto contrasto.

Sito web del negozio Dumpling Time con tema rosso e rosa con la modalità ad alto contrasto attiva e il pulsante di acquisto ora è fortemente messo a fuoco con un contorno rosso spesso Sito web del negozio Dumpling Time con tema blu e verde con la modalità ad alto contrasto attivata e il pulsante di acquisto ora è fortemente evidenziato con un contorno blu spesso

Controllo accessibilità:

  • Tutte le pagine hanno titoli univoci
  • I colori hanno un rapporto di contrasto sufficiente
  • L'HTML semantico garantisce un'interazione logica
  • Tutti i controlli sono raggiungibili dagli screen reader
  • Il cursore utilizza gli attributi ARIA per fornire un'etichetta
  • Il selettore colori ha un corretto intrappolamento della messa a fuoco
  • Vengono annunciati modifiche, errori e notifiche
  • La modalità ad alto contrasto è attivata

13. Complimenti!

Congratulazioni, hai risolto i problemi comuni di accessibilità web nella tua app Angular. 🎉

Per visualizzare tutte le soluzioni, consulta il ramo main.

Il sito web del negozio Dumpling Time con tema rosso e rosa mostra tutte le modifiche apportate in questo codelab Il sito web del negozio Dumpling Time con tema blu e verde mostra tutte le modifiche apportate in questo codelab Controllo Lighthouse di Chrome DevTools con un punteggio di 100/100

Ora conosci i passaggi chiave necessari per risolvere otto problemi comuni di accessibilità nella tua applicazione Angular.

Scopri di più

Dai un'occhiata a questi codelab:

Leggi questi materiali: