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 principali attività della vita. In tutto il mondo, circa il 15% della popolazione mondiale, ovvero più di 1 miliardo di persone, ha qualche forma di disabilità, con circa il 2-4% che presenta difficoltà significative.

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

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

Per un'introduzione approfondita a problemi e tecniche per la progettazione di app accessibili, consulta la pagina 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
  • Soddisfa tutte le linee guida sull'accessibilità, WCAG 2.0 e ARIA 1.2 e supera i controlli di accessibilità di axe e Lighthouse.

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

Cosa imparerai a fare

Scoprirai otto problemi di accessibilità comuni nelle app Angular che interessano gli utenti, nonché come identificarli e risolverli. Nello specifico:

  • Utilizzare gli Strumenti per sviluppatori di Google Chrome, Lighthouse e axe per verificare l'accessibilità dell'app
  • Risolvere le insidie relative alle app a pagina singola (APS) con titoli di pagina univoci
  • Risolvere i problemi di contrasto dei colori basso per gli utenti ipovedenti
  • Utilizzare HTML semantico per garantire che gli screen reader navighino correttamente nella pagina
  • Utilizza Angular Material e annulla l'annidamento dei 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 di Angular CDK
  • Utilizzare FocusTrap per la navigazione con lo screen reader dei componenti personalizzati
  • Annunciare le notifiche con LiveAnnouncer di CDK
  • Rilevare gli utenti con la modalità HighContrast e implementare temi ad alto contrasto

Che cosa ti serve

2. Configurazione

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

Clonare il repository e gestire l'app

VSCode o un IDE locale è il metodo consigliato per l'utilizzo di 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 e cd angular-accessibility/ nel repository.
  3. Consulta il ramo del codice di avvio git checkout get-started.
  4. Apri il codice in VSCode o nel tuo IDE preferito.
  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 un valore 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 in questo codelab e ha poche funzionalità.

Sito web del negozio Dumpling Time in tema viola e verde

Esplora la demo

Per iniziare, esamina le tre funzionalità della tua app:

  1. Utilizza la barra di navigazione per visualizzare i percorsi Il nostro negozio, La nostra storia e Come trovarci e per vedere i dettagli sulla società di gnocchi.
  2. Cambia i temi per attivare/disattivare la modalità Luce e Buio.
  3. Personalizza i ripieni, la quantità e il colore dei ravioli del tuo ordine.
  4. Seleziona Acquista per registrare l'ordine personalizzato nella console.

Utilizzare Angular per risolvere i problemi comuni di accessibilità web

In questo codelab, ti concentri 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 sai quale problema risolvere?

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

Nello stato attuale del web, è obbligatorio testare manualmente l'accessibilità.

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 verificare una vasta gamma di concetti di accessibilità che includono 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 nostro computer e naviga nell'app con la navigazione da tastiera. Per ulteriori informazioni, consulta Semantica e screen reader.

Fai pratica 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 attivarlo. Per attivare/disattivare VoiceOver, premi rapidamente il TouchID tre volte tenendo premuto il tasto Command.

In questo corso, testi principalmente i problemi manualmente e utilizzi strumenti automatici per verificare funzionalità automatizzabili specifiche.

Test automatici

Utilizzi anche alcuni strumenti di sviluppo per automatizzare e controllare la tua app. Questi strumenti ti consentono di verificare, ad esempio, la presenza di testo alternativo in un'immagine o il rapporto di contrasto di un colore di testo. Puoi considerare questi strumenti come linters: possono riconoscere la presenza del testo alternativo, ma devi verificare manualmente che i contenuti siano logici e forniscano valore.

Strumenti per sviluppatori di Lighthouse e 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 a11y.

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

Ascia

  1. Installa l'estensione axe DevTools. Per vedere l'estensione potrebbe essere necessario riavviare il browser.
  2. Apri gli Strumenti per sviluppatori di Chrome.
  3. Seleziona la scheda axe DevTools, quindi Scansiona tutta la pagina per eseguire una scansione DevTools di Axe.

Analisi tramite lint

Puoi utilizzare le regole ESLint Angular per lint del codice per gli attributi a11y automatizzabili.

In eslint.json, aggiungi i seguenti elementi applicabili 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 regole ESLint più recenti su GitHub.

Il tuo punto di partenza

Con 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 di accessibilità:

  • 🛑 Tutte le pagine hanno lo stesso titolo
  • 🛑 Gli elementi devono avere un contrasto di colore 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 screen reader si concentra nel selettore dei colori e esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità Contrasto elevato non è attiva

4. Definire titoli di pagina univoci

Fornire titoli di pagina unici e concisi aiuta gli utenti che utilizzano i 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 pagina singola e, di conseguenza, la maggior parte delle transizioni, come il passaggio a una nuova pagina, non comporta il ricaricamento della pagina. Fino a poco tempo fa, ciò significava che ogni pagina aveva un titolo identico e non forniva alcun valore per comprenderne i contenuti o lo scopo.

In Angular v14, il router ha aggiunto un metodo integrato per definire i titoli delle pagine univoci in modo immediato. Questo approccio offre un approccio semplificato per garantire che gli sviluppatori seguano le best practice per i titoli delle pagine.

Entro la fine di questa sezione, la tua app supererà il seguente controllo:

  • 🛑 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 questo problema, attiva lo screen reader e spostati tra le schede Il nostro negozio, La nostra storia e Trovaci 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.

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

Browser Chrome con tre schede aperte con titolo della pagina identico: "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 percorsi 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, verrà importato e utilizzato automaticamente Router's Title Service per gestire la modifica del titolo della pagina durante la navigazione in modo che corrisponda alla proprietà del titolo definita nelle nostre route. Puoi anche gestire titoli di pagina più complicati utilizzando un elemento TitleStrategy personalizzato.

Verificare le modifiche

Riattiva lo screen reader e verifica le modifiche. Ora le pagine dovrebbero avere titoli univoci.

Browser Chrome con tre schede aperte con titolo pagina univoco: "Il nostro negozio - a11y in Angular", "La nostra storia - a11y in Angular", "Come trovarci - a11y in Angular"

Controllo di accessibilità:

  • Tutte le pagine hanno titoli univoci.
  • 🛑 Gli elementi devono avere un contrasto di colore 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 screen reader si concentra nel selettore dei colori e esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità Contrasto elevato non è attiva

5. Assicurati che il contrasto di colore sia adeguato

Il tuo design potrebbe sembrare accattivante, ma non lo è se le persone con disabilità visive, ad esempio 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 disabilità visive e daltonici.

Entro la fine di questa sezione, la tua app supererà il seguente controllo:

  • 🛑 Gli elementi devono avere un contrasto di colore 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 a 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 vedere che il contrasto è 1,85, molto al di sotto dei requisiti WCAG.

Elemento di ispezione di Chrome DevTools di un pulsante Home con contrasto basso

  1. Per individuare questi problemi di rapporto di contrasto, esegui il controllo Accessibilità in Lighthouse o sulla scansione dell'ascia.

I risultati del controllo Lighthouse di Chrome DevTools presentano un errore: "Il rapporto di contrasto tra i colori di sfondo e primo piano non è sufficiente"

Cambiare il colore del tema Material

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

Aggiorna il tema Materiale 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 di accessibilità integrati degli Strumenti per sviluppatori di Chrome per trovare un colore che soddisfi gli standard o per aggiornare i singoli valori dei colori in Sass.

Verificare le modifiche

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

Chrome DevTools controlla 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 screen reader si concentra nel selettore dei colori e esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità HighContrast non è attivata

6. Utilizza HTML semantico

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

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

Entro la fine di questa sezione, la tua app supererà il seguente controllo:

  • 🛑 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. Usa la navigazione tra le schede per fare clic sulla scheda La nostra storia.
  3. Tieni presente che l'ordine delle schede non è sequenziale.
  4. Fai clic su Acquista.
  5. Tieni presente che il pulsante non viene riconosciuto come tale.

Risultati del controllo di Chrome DevTools Lighthouse con un errore: gli elementi di intestazione non si trovano in un ordine decrescente in sequenza Le intestazioni ordinate correttamente che non saltano livelli comunicano la struttura semantica della pagina, semplificando la navigazione e la comprensione quando si utilizzano tecnologie per la disabilità. Ulteriori informazioni.

Modificare un <div> in un <button>

Sostituisci il <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 HTML semantico e applica gli stili 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>

Verificare le modifiche

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

Controllo di 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 screen reader si concentra nel selettore dei colori e esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità Contrasto elevato non è attiva

7. Creare controlli selezionabili con Angular Material

Un modello di interazione complicato per i servizi di accessibilità è costituito dai controlli nidificati. Pensa a elementi secondari del menu o caselle di controllo nidificate. Come fai a indicare a un utente che può selezionare un sottogruppo di opzioni o passare a un elemento 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 elenco di Angular Material per creare un esempio di questo pattern di interazione.

Entro la fine di questa sezione, la tua app supererà il seguente controllo:

  • 🛑 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 il problema, attiveremo lo screen reader e tenteremo di selezionare una casella di controllo nidificata.

  1. Attiva VoiceOver.
  2. Seleziona diversi gusti per il ripieno.
  3. Tieni presente che le caselle di controllo per i genitori non specificano i bambini quando vengono lette dalla voce fuori campo. Come fai a sapere che la casella di controllo Vegano non è selezionata ora che hai deselezionato la casella di controllo Bok Choy?

Menu della casella di controllo per il ripieno con le opzioni: Ripieni vegani Bok Choy Tofu e Shitake Meat Chicken Impossible Meat

Accessibilità in Materiale Angular

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

Sostituire le caselle di controllo con le caselle di controllo Materiale

  1. Innanzitutto, aggiungi il nuovo elenco di ripieni e una variabile per memorizzare i gusti 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 disordinato raggruppamento 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 parte del Sass non utilizzato in src/app/shop/shop.component.scss per semplificare lo stile.

Verificare le modifiche

Riattiva lo screen reader e verifica le modifiche. Ora le caselle di controllo sono selezionabili e navigabili in modo più intuitivo con uno screen reader.

Menu della casella di controllo del ripieno con le voci: Ripieni Bok Choy e Chili Crunch Tofu e funghi Pollo e zenzero Impossible Meat & Spinaci quantità

Controllo di 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 screen reader si concentra nel selettore dei colori e esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità HighContrast non è attivata

8. Fornire etichette di controllo con ARIA

Hai modificato i componenti HTML e Material semantici della tua app Angular, ma alcuni componenti richiedono attributi specifici per essere completamente navigati 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. Ti consente di specificare attributi che modificano il modo in cui un elemento viene tradotto nella struttura ad albero di accessibilità.

Entro la fine di questa sezione, la tua app supererà il seguente controllo:

  • 🛑 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 dispositivo di scorrimento della quantità e modifica il valore.
  3. Tieni presente che l'etichetta del valore non è presente.

Risultati del controllo di Chrome DevTools Lighthouse 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 annunciano con un nome generico, rendendolo inutilizzabile per gli utenti che si affidano agli screen reader. Ulteriori informazioni.

Utilizzare gli attributi ARIA

Controllo delle etichette utilizzando aria-label e <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>

Verificare le modifiche

Riattiva lo screen reader e verifica le modifiche. Ora puoi spostare il cursore.

Controllo Lighthouse di Chrome DevTools con superamento del controllo per i controlli ARIA degli screen reader.

Controllo di 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 dispositivo di scorrimento utilizza gli attributi ARIA per fornire un'etichetta
  • 🛑 Lo screen reader si concentra nel selettore dei colori e esce dalla finestra di dialogo
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità Contrasto elevato non è attiva

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

Fino ad ora, hai fatto affidamento sugli strumenti Angular integrati per risolvere i problemi di accessibilità più comuni. Ora esaminiamo il modulo a11y del CDK e come può aiutarci a risolvere problemi più complicati e specifici di Angular.

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

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

Importa il modulo

Aggiungi il modulo all'app:

src/app/app.module.ts

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

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

A cosa serve '@angular/cdk/a11y'?

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

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

Per ulteriori informazioni su tutti gli altri servizi forniti da @angular/cdk/a11y, vedi Accessibilità.

10. Controllare la messa a fuoco con FocusTrap

Quando una finestra di dialogo o una finestra modale è aperta, un utente sta interagendo solo al suo interno. Se consenti all'elemento attivo di eseguire l'escape all'esterno della finestra di dialogo, si combina i contesti e si crea uno stato in cui l'utente non sa in quale parte della pagina si trova.

In Angular, la direttiva cdkTrapFocus blocca lo stato attivo della tastiera tab- all'interno di un elemento. Questo valore deve essere utilizzato per creare esperienze accessibili per componenti come le finestre di dialogo modali, in cui lo stato attivo deve essere limitato.

Al termine di questa sezione, la tua app avrà superato il seguente controllo:

  • 🛑 Lo stato attivo dello screen reader nel selettore colori chiude la 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 delle schede per modificare il colore.
  3. Controlla se l'ordine di messa a fuoco e il blocco della messa a fuoco sono intuitivi nel selettore dei colori.

Sito web del negozio Dumpling Time in tema viola e verde con finestra di dialogo aperta per selezionare il colore della confezione dei ravioli

Aggiungi FocusTrap

cdkFocusTrap può essere utilizzato per intercettare e controllare l'ordine di attivazione nei componenti personalizzati. L'utilizzo di mat-dialog-content è sufficiente per risolvere la maggior parte dei problemi bloccando il fuoco 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> nella finestra di dialogo del selettore di 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>

Verificare le modifiche

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

Controllo di 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 dispositivo di scorrimento utilizza gli attributi ARIA per fornire un'etichetta
  • Il selettore dei colori ha un corretto blocco della messa a fuoco
  • 🛑 Modifiche, errori e notifiche non vengono annunciati
  • 🛑 La modalità HighContrast non è attiva

11. Annunciare le modifiche con LiveAnnouncer

Gli screen reader devono essere avvisati quando qualcosa nella pagina cambia. Immagina di provare a inviare un modulo o a completare un acquisto senza sapere che è stato visualizzato un errore che impedisce l'invio del modulo. È frustrante!

LiveAnnouncer viene utilizzato per annunciare i messaggi per gli utenti di screen reader che utilizzano una regione aria-live per garantire che gli screen reader vengano avvisati delle notifiche e delle modifiche in tempo reale della pagina. Per ulteriori informazioni sulle regioni aria-live, consulta WAI-ARIA del W3C. In Angular, chiamare LiveAnnouncer come servizio è una soluzione più testabile rispetto agli attributi aria-live.

Entro la fine di questa sezione, la tua app supererà il seguente controllo:

  • 🛑 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 Acquista senza compilare i campi del modulo:

  1. Attiva VoiceOver.
  2. Utilizza la navigazione a schede per cambiare il colore e effettuare un falso acquisto.
  3. Nota che non c'è alcuna indicazione del colore selezionato quando esci dalla finestra di dialogo e l'acquisto non viene letto.

Sito web del negozio Dumpling Time in tema rosa e rosso con finestra di dialogo aperta per selezionare il colore della confezione dei ravioli

Aggiungere il LiveAnnouncer al codice

Aggiungi LiveAnnouncer e annuncia sia la selezione del colore sia l'acquisto falso come stringa. In un'implementazione reale, questo valore potrebbe essere letto quando accedi a un sistema di pagamento di terze parti o per errori nei moduli.

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

Verificare le modifiche

Riattiva lo screen reader e verifica le modifiche. Ora riceverai una notifica per gli errori.

Controllo dell'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 dispositivo di scorrimento utilizza gli attributi ARIA per fornire un'etichetta
  • Il selettore dei colori ha un corretto blocco della messa a fuoco
  • Le modifiche, gli errori e le notifiche vengono annunciati
  • 🛑 La modalità HighContrast non è attivata

12. Attiva modalità Contrasto elevato

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

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

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

Al termine di questa sezione, la tua app avrà superato il seguente controllo:

  • 🛑 La modalità HighContrast non è attiva

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. Tieni presente che l'applicazione non è cambiata.

Aggiungere il supporto della modalità ad alto contrasto

In styles.scss, utilizza il mix cdk-high-contrast fornito in @angular/cdk/a11y per aggiungere un contorno ai pulsanti in modalità ad 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);
    }
  }
}

Verificare 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 in tema rosso e rosa con la modalità ad alto contrasto attivata e il pulsante di acquisto ora è molto in evidenza con un contorno rosso spesso Sito web del negozio Dumpling Time in tema blu e verde con la modalità ad alto contrasto attivata e il pulsante di acquisto è ora fortemente messo a fuoco con un contorno blu spesso

Controllo di 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 dispositivo di scorrimento utilizza gli attributi ARIA per fornire un'etichetta
  • Il selettore dei colori ha un corretto blocco della messa a fuoco
  • Le modifiche, gli errori e le notifiche vengono annunciati
  • La modalità ad alto contrasto è attivata

13. Complimenti!

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

Per visualizzare tutte le soluzioni, controlla il ramo main.

Sito web Dumpling Time Shop con tema rosso e rosa che mostra tutte le modifiche apportate in questo codelab Il sito web di Dumpling Time Shop 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 errori comuni relativi all'accessibilità nella tua applicazione Angular.

Scopri di più

Dai un'occhiata a questi codelab:

Leggi questi materiali: