Barrierefreiheit von Angular-Apps erstellen

1. Hinweis

Schwarzes Angular-Logo

Barrierefreiheit ist ein wichtiger Bestandteil der Webentwicklung. Sie sorgt dafür, dass Nutzer Apps wahrnehmen, verstehen, darin navigieren und mit ihnen interagieren können. Tatsächlich hat jeder vierte Erwachsene in den USA eine Behinderung, die sich auf seine wichtigsten Lebensaktivitäten auswirkt. Weltweit haben etwa 15 % der Weltbevölkerung – mehr als 1 Milliarde Menschen – eine Behinderung. Bei etwa 2 bis 4 % der Weltbevölkerung ist die Behinderung schwerwiegend.

Häufige Beeinträchtigungen, die die Nutzung des Internets beeinträchtigen, sind Blindheit oder eingeschränktes Sehvermögen, Taubheit oder Hörschwäche, eingeschränkte motorische Fähigkeiten, kognitive Behinderungen und Farbenblindheit. Dies ist nur eine unvollständige Liste.

In diesem Kurs ist „a11y“ eine Abkürzung für „Barrierefreiheit“. Beachten Sie, dass auf das a 11 Zeichen und ein y folgen.

Eine ausführliche Einführung in Probleme und Techniken zum Entwerfen barrierefreier Apps finden Sie unter Barrierefreiheit.

Umfang

  • Best Practices und integrierte Techniken verwenden, um häufige Probleme mit der Barrierefreiheit im Web in einer Demo-Angular-App für einen Dumpling-Shop zu beheben
  • Alle Richtlinien für Barrierefreiheit, WCAG 2.0 und ARIA 1.2 müssen eingehalten werden und die Barrierefreiheitsprüfungen von axe und Lighthouse müssen bestanden werden.

Website des Shops „Dumpling Time“ in Rosa und Rot Website des Dumpling Time-Shops in lila und grün

Lerninhalte

Sie erfahren mehr über acht häufige Barrierefreiheitsprobleme in Angular-Apps, die sich auf Nutzer auswirken, wie Sie sie erkennen und beheben können. Dazu führen Sie die folgenden Schritte aus:

  • Barrierefreiheit Ihrer App mit den Google Chrome-Entwicklertools, Lighthouse und axe prüfen
  • Fallstricke bei Single-Page-Apps (SPAs) mit eindeutigen Seitentiteln vermeiden
  • Probleme mit geringem Farbkontrast für Nutzer mit eingeschränktem Sehvermögen beheben
  • Semantisches HTML verwenden, damit Screenreader die Seite richtig durchlaufen
  • Angular Material verwenden und Steuerelemente entnesten, damit Screenreader auf alle Steuerelemente zugreifen können
  • ARIA-Unterstützung für Screenreader hinzufügen
  • Angular CDK-Paket „a11y“ importieren und verwenden
  • FocusTrap für die Screenreader-Navigation in benutzerdefinierten Komponenten verwenden
  • Benachrichtigungen mit dem CDK LiveAnnouncer ansagen lassen
  • Nutzer mit dem Modus mit hohem Kontrast erkennen und ein Design mit hohem Kontrast implementieren

Voraussetzungen

2. Einrichten

Code abrufen

Alles, was Sie für dieses Projekt benötigen, befindet sich in einem GitHub-Repository. Klonen Sie zuerst den Code und öffnen Sie ihn in Ihrer bevorzugten Entwicklungsumgebung.

Repository klonen und App bereitstellen

VS Code oder eine lokale IDE sind die empfohlene Methode für dieses Codelab.

  1. Öffnen Sie einen neuen Browsertab und rufen Sie https://github.com/googlecodelabs/angular-accessibility auf.
  2. Verzweigen und klonen Sie das Repository und cd angular-accessibility/ in das Repository.
  3. Sehen Sie sich den Starter-Code-Zweig git checkout get-started an.
  4. Öffnen Sie den Code in VSCode oder Ihrer bevorzugten IDE.
  5. Führen Sie npm install aus, um die Abhängigkeiten zu installieren, die zum Ausführen des Servers erforderlich sind.
  6. Führen Sie ng serve aus, um den Server auszuführen.
  7. Öffnen Sie einen Browsertab für http://localhost:4200.

3. Baseline festlegen

Wo möchten Sie starten?

Ausgangspunkt ist eine einfache Restaurant-App, die für dieses Codelab entwickelt wurde. Der Code wurde vereinfacht, um die Konzepte in diesem Codelab zu veranschaulichen. Er bietet nur wenige Funktionen.

Website des Dumpling Time-Shops in lila und grün

Demo ansehen

Sehen Sie sich dazu die drei Funktionen Ihrer App an:

  1. Über die Navigationsleiste können Sie die Routen Unser Geschäft, Unsere Geschichte und So finden Sie uns aufrufen und Details zum Unternehmen für Knödel sehen.
  2. Sie können das Design ändern, um den hellen und dunklen Modus zu aktivieren oder zu deaktivieren.
  3. Passen Sie die Füllung, Menge und Farbe Ihrer Bestellung an.
  4. Wählen Sie Kaufen aus, um Ihre benutzerdefinierte Bestellung in der Console zu protokollieren.

Häufige Probleme mit der Web-Barrierefreiheit mit Angular beheben

In diesem Codelab konzentrieren Sie sich auf die Barrierefreiheit der vorhandenen Funktionen dieser App. Sie beginnen damit, Barrierefreiheitsprobleme in Ihrer App zu identifizieren, und verwandeln dann das 🛑 in ein ✅, indem Sie eine Lösung implementieren.

Woher wissen Sie, was Sie korrigieren müssen?

Beginnen Sie jedes Beispiel damit, das Problem mit der Barrierefreiheit mithilfe einer Kombination aus manuellen und automatisierten Tests zu erkennen.

Im aktuellen Zustand des Webs ist das manuelle Testen der Barrierefreiheit obligatorisch.

Es gibt zwar Tools, mit denen sich Barrierefreiheitsprobleme erkennen lassen, aber kein Tool kann bestätigen, dass eine App vollständig barrierefrei ist. Bei manuellen Tests werden eine Vielzahl von Barrierefreiheitskonzepten getestet, darunter die logische Reihenfolge von Inhalten und die Gleichheit von Funktionen.

Manuelle Tests

Um die Barrierefreiheit in diesem Kurs manuell zu testen, aktivieren Sie den integrierten Screenreader Ihres Computers und navigieren Sie mit der Tastatur durch Ihre App. Weitere Informationen finden Sie unter Semantik und Screenreader.

Üben Sie, indem Sie den Screenreader aktivieren und auf dem Bildschirm navigieren.

Sie können den in MacOS integrierten Screenreader VoiceOver verwenden. Klicken Sie auf Systemeinstellungen > Bedienungshilfen > VoiceOver > VoiceOver aktivieren. Wenn Sie VoiceOver ein- oder ausschalten möchten, drücken Sie schnell dreimal auf Touch ID, während Sie die Taste Command gedrückt halten.

In diesem Kurs testen Sie Probleme hauptsächlich manuell und verwenden automatisierte Tools, um bestimmte automatisierbare Funktionen zu prüfen.

Automatisierte Tests

Außerdem verwenden Sie einige Entwicklungstools, um Ihre App zu automatisieren und zu prüfen. Mit diesen Tools können Sie beispielsweise prüfen, ob ein Bild Alt-Text enthält oder wie das Kontrastverhältnis einer Textfarbe ist. Diese Tools können als Linter betrachtet werden. Sie können erkennen, ob Alternativtext vorhanden ist. Sie müssen jedoch manuell prüfen, ob der Inhalt logisch ist und einen Mehrwert bietet.

Lighthouse und Chrome-Entwicklertools

  1. Öffnen Sie die Chrome-Entwicklertools.
  2. Wählen Sie den Tab Lighthouse und dann das Kästchen Bedienungshilfen aus.
  3. Klicken Sie auf Bericht generieren, um eine Lighthouse-Prüfung zur Barrierefreiheit durchzuführen.

Beispieltab für Lighthouse mit Schaltfläche zum Generieren eines Berichts auf einem Chrome-Entwicklertools-Tab

Axt

  1. Installieren Sie die axe DevTools-Erweiterung. Möglicherweise müssen Sie Ihren Browser neu starten, um die Erweiterung zu sehen.
  2. Öffnen Sie die Chrome-Entwicklertools.
  3. Wählen Sie den Tab axe DevTools und dann Scan all of my page (Meine gesamte Seite scannen) aus, um einen axe DevTools-Scan auszuführen.

Linting

Mit den Angular ESLint-Regeln können Sie Ihren Code auf automatisierbare A11Y-Attribute prüfen.

Fügen Sie in eslint.json die folgenden Zeilen hinzu, die sich auf die Barrierefreiheit beziehen:

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

Weitere Informationen finden Sie in den aktuellen ESLint-Regeln auf GitHub.

Ihre Ausgangssituation

Mit den neuen Testmethoden können Sie die folgenden Probleme in Ihrer App mithilfe von Lighthouse- und axe-Prüfungen sowie manuellen VoiceOver-Tests ermitteln:

Lighthouse-Prüfung in den Chrome-Entwicklertools mit einem Ergebnis von 82

Prüfung der Barrierefreiheit:

  • 🛑 Alle Seiten haben denselben Seitentitel
  • 🛑 Elemente müssen einen ausreichenden Farbkontrast aufweisen
  • 🛑 HTML sollte eine logische Reihenfolge, einen Namen und eine Rolle haben
  • 🛑 Verschachtelte Kästchen können nicht mit Screenreadern ausgewählt werden
  • 🛑 Screenreader liest keine Schiebereglerwerte vor
  • 🛑 Screenreader-Fokus im Farbwähler verlässt das Dialogfeld
  • 🛑 Änderungen, Fehler und Benachrichtigungen werden nicht angekündigt
  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

4. Eindeutige Seitentitel definieren

Einzigartige, prägnante Seitentitel helfen Nutzern, die A11y-Dienste verwenden, den Inhalt und Zweck einer Webseite schnell zu erfassen. Seitentitel sind für Nutzer mit Sehbehinderungen von entscheidender Bedeutung, da sie das erste Seitenelement sind, das von Screenreader-Software angekündigt wird.

Angular ist eine Single-Page-App. Daher wird bei den meisten Übergängen, z. B. beim Wechsel zu einer neuen Seite, die Seite nicht neu geladen. Bis vor Kurzem hatte jede Seite denselben Seitentitel, der keinen Aufschluss über den Inhalt oder Zweck der Seite gab.

In Angular v14 wurde dem Router eine integrierte Methode zum Definieren eindeutiger Seitentitel hinzugefügt. So wird sichergestellt, dass Entwickler Best Practices für Seitentitel befolgen.

Am Ende dieses Abschnitts besteht Ihre App die folgende Prüfung:

  • 🛑 Alle Seiten haben denselben Seitentitel

Sie finden die einzelnen Schritte unter dem Kommentar: TODO: #4. Define unique page titles.

Problem identifizieren

So können Sie dieses Problem erkennen: Aktivieren Sie die Sprachausgabe und wechseln Sie zwischen den Tabs Unser Shop, Über uns und Kontakt, um die Seitentitel zu sehen:

  1. Aktivieren Sie VoiceOver.
  2. Verwenden Sie die Tab-Navigation, um zwischen Seiten zu wechseln.
  3. Prüfen Sie, ob der Seitentitel in Angular immer „a11y“ lautet.

Das ist ein Problem, weil Seitentitel eindeutig sein müssen, damit Nutzer schnell erkennen können, worum es auf der Seite geht, ohne sie durchsuchen zu müssen.

Chrome-Browser mit drei geöffneten Tabs mit dem identischen Seitentitel „a11y in Angular“

Aussagekräftige Seitentitel hinzufügen

Wenn sich eine Seite oder Ansicht ändert, sollten Sie den Seitentitel richtig verwalten. Um dieses Problem zu beheben, verwenden Sie die integrierte Router.title-Eigenschaft von Angular, um eindeutige Titel für jede Ihrer Seiten zu definieren.

  1. Fügen Sie jeder der drei definierten Routen einen eindeutigen Titel hinzu:

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 },
];

Dadurch wird Router's Title Service automatisch importiert und verwendet, um den Seitentitel bei der Navigation so zu ändern, dass er mit der in unseren Routen definierten title-Property übereinstimmt. Sie können auch komplexere Seitentitel mit einem benutzerdefinierten TitleStrategy verwalten.

Änderungen bestätigen

Aktivieren Sie den Screenreader wieder und überprüfen Sie Ihre Änderungen. Die Seiten sollten jetzt eindeutige Titel haben.

Chrome-Browser mit drei geöffneten Tabs mit eindeutigen Seitentiteln: „Our Shop – a11y in Angular“, „Our Story – a11y in Angular“, „Find Us – a11y in Angular“

Prüfung der Barrierefreiheit:

  •  Alle Seiten haben eindeutige Seitentitel.
  • 🛑 Elemente müssen einen ausreichenden Farbkontrast aufweisen
  • 🛑 HTML sollte eine logische Reihenfolge, einen Namen und eine Rolle haben
  • 🛑 Verschachtelte Kästchen können nicht mit Screenreadern ausgewählt werden
  • 🛑 Screenreader liest keine Schiebereglerwerte vor
  • 🛑 Screenreader-Fokus im Farbwähler verlässt das Dialogfeld
  • 🛑 Änderungen, Fehler und Benachrichtigungen werden nicht angekündigt
  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

5. Für ausreichenden Farbkontrast sorgen

Ihr Design mag cool aussehen, aber es ist nicht gut, wenn Menschen mit Sehbehinderungen wie Farbenblindheit Ihre Inhalte nicht lesen können. In den Richtlinien für barrierefreie Webinhalte (WCAG 2.0) sind eine Reihe von Farbkontrastverhältnissen definiert, die sicherstellen, dass Inhalte barrierefrei sind. In Angular und im Web können Sie Farbpaletten definieren, die dafür sorgen, dass Ihre Komponenten diesen Standards entsprechen und für Nutzer mit Sehbehinderung und Farbenblindheit sichtbar sind.

Am Ende dieses Abschnitts besteht Ihre App die folgende Prüfung:

  • 🛑 Elemente müssen einen ausreichenden Farbkontrast aufweisen

Sie finden die einzelnen Schritte unter den Kommentaren: TODO: #5. Ensure adequate color contrast.

Probleme mit niedrigem Kontrast mithilfe der Chrome-Entwicklertools erkennen

Verwenden Sie die Chrome-Entwicklertools, um die Elemente in Ihrer App zu untersuchen und das Problem zu ermitteln.

  1. Mit dem Tool „Untersuchen“ können Sie die Schaltflächen mit den Menüsymbolen ansehen. Der Kontrast beträgt 1, 85 und liegt damit weit unter den WCAG-Anforderungen.

Chrome-Entwicklertools: Element „Home-Schaltfläche“ mit geringem Kontrast wird untersucht

  1. Führen Sie den Barrierefreiheits-Audit in Lighthouse oder den Scan von axe aus, um diese Probleme mit dem Kontrastverhältnis zu sehen.

Chrome-Entwicklertools – Lighthouse-Prüfungsergebnisse mit dem Fehler „Das Kontrastverhältnis von Hintergrund- und Vordergrundfarben ist nicht ausreichend“

Material-Designfarbe ändern

Das Farbschema Ihrer Komponente wird in Ihrem benutzerdefinierten Material-Design definiert. Sie aktualisieren den Designwert, damit er den Richtlinien für das Farbkontrastverhältnis entspricht.

Aktualisieren Sie Ihr Material-Design, um eine dunklere Textfarbe zu verwenden und das Kontrastverhältnis Ihrer Symbole zu erhöhen:

src/styles.scss

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

Sie können auch die integrierten Barrierefreiheitstools der Chrome-Entwicklertools verwenden, um eine Farbe zu finden, die den Standards entspricht, oder einzelne Farbwerte in Sass aktualisieren.

Änderungen bestätigen

Sehen Sie sich die Elemente noch einmal an und prüfen Sie die Änderungen. Das Design sollte jetzt einen ausreichenden Farbkontrast aufweisen.

Chrome DevTools: Element einer Schaltfläche „Startseite“ mit ausreichendem Kontrast wird untersucht

Prüfung der Barrierefreiheit

  •  Alle Seiten haben eindeutige Seitentitel.
  •  Farben haben ein ausreichendes Kontrastverhältnis
  • 🛑 HTML sollte eine logische Reihenfolge, einen Namen und eine Rolle haben
  • 🛑 Verschachtelte Kästchen können nicht mit Screenreadern ausgewählt werden
  • 🛑 Screenreader liest keine Schiebereglerwerte vor
  • 🛑 Screenreader-Fokus im Farbwähler verlässt das Dialogfeld
  • 🛑 Änderungen, Fehler und Benachrichtigungen werden nicht angekündigt
  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

6. Semantisches HTML verwenden

Native HTML-Elemente erfassen eine Reihe von Standardinteraktionsmustern, die für die Barrierefreiheit wichtig sind. Ein Absatz kann als „span“ und ein „div“ als Schaltfläche formatiert werden. Semantische HTML-Elemente sorgen jedoch dafür, dass Screenreader und die Tastaturnavigation die Interaktionen und Steuerelemente Ihres HTML-Codes verstehen.

Beim Erstellen von Angular-Komponenten sollten Sie diese nativen Elemente nach Möglichkeit direkt wiederverwenden, anstatt gut unterstützte Verhaltensweisen neu zu implementieren. So wird sichergestellt, dass die Seite eine gute Inhaltsstruktur und einen natürlichen Inhaltsfluss hat und dass die Tabulatoren in einer logischen Reihenfolge angeordnet sind, um Nutzern die Navigation auf der Website mit der Tastatur zu erleichtern.

Am Ende dieses Abschnitts besteht Ihre App die folgende Prüfung:

  • 🛑 HTML sollte eine logische Reihenfolge, einen Namen und eine Rolle haben

Sie finden die einzelnen Schritte unter den Kommentaren: TODO: #6. Use Semantic HTML.

Problem identifizieren

  1. Aktivieren Sie VoiceOver.
  2. Klicken Sie sich mit der Tabulatortaste zum Tab Unsere Geschichte durch.
  3. Die Reihenfolge der Tabs ist nicht fortlaufend.
  4. Klicken Sie auf Purchas.
  5. Die Schaltfläche wird nicht als Schaltfläche erkannt.

Chrome-Entwicklertools – Lighthouse-Prüfungsergebnisse mit Fehler: Überschriftenelemente sind nicht in absteigender Reihenfolge angeordnet. Richtig geordnete Überschriften, die keine Ebenen überspringen, geben der Seite eine semantische Struktur. Nutzer von Hilfstechnologien können sich so leichter auf der Seite zurechtfinden und die Inhalte besser verstehen. Weitere Informationen

<div> in <button> ändern

Ersetzen Sie das benutzerdefinierte <div> durch eine Material-Schaltfläche:

src/app/shop/shop.component.html

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

Überschriftenelemente sequenziell verwenden

Ordnen Sie den Text neu an, um semantisches HTML zu verwenden, und wenden Sie das Styling mit der Typografie von Angular Material an:

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>

Änderungen bestätigen

Aktivieren Sie den Screenreader wieder und überprüfen Sie Ihre Änderungen. VoiceOver erkennt die Schaltfläche jetzt und der Text wird in einer logischen Reihenfolge vorgelesen.

Prüfung der Barrierefreiheit:

  •  Alle Seiten haben eindeutige Seitentitel.
  •  Farben haben ein ausreichendes Kontrastverhältnis
  •  Semantisches HTML sorgt für logische Interaktion
  • 🛑 Verschachtelte Kästchen können nicht mit Screenreadern ausgewählt werden
  • 🛑 Screenreader liest keine Schiebereglerwerte vor
  • 🛑 Screenreader-Fokus im Farbwähler verlässt das Dialogfeld
  • 🛑 Änderungen, Fehler und Benachrichtigungen werden nicht angekündigt
  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

7. Auswählbare Steuerelemente mit Angular Material erstellen

Ein kompliziertes Interaktionsmuster für Bedienungshilfen sind verschachtelte Steuerelemente. Denken Sie an Untermenüs oder verschachtelte Kästchen. Wie wird einem Nutzer angezeigt, dass er eine Untergruppe von Optionen auswählen oder zu einem übergeordneten Menüpunkt zurückkehren kann?

In Angular können Sie Menüs und Steuerelemente vereinfachen, um navigierbare Komponenten zu erstellen. In diesem Beispiel verwenden Sie die Listbox von Angular Material, um ein Beispiel für dieses Interaktionsmuster zu erstellen.

Am Ende dieses Abschnitts besteht Ihre App die folgende Prüfung:

  • 🛑 Verschachtelte Kästchen können nicht mit Screenreadern ausgewählt werden

Sie finden die einzelnen Schritte unter den Kommentaren: TODO: #7. Create selectable controls with Angular Material.

Problem identifizieren

Um dieses Problem zu identifizieren, aktivieren wir unsere Screenreader-Funktion und versuchen, ein verschachteltes Kästchen auszuwählen.

  1. Aktivieren Sie VoiceOver.
  2. Wählen Sie verschiedene Füllungen aus.
  3. Beachten Sie, dass die übergeordneten Checkboxen beim Vorlesen durch VoiceOver keine untergeordneten Elemente angeben. Woher wissen Sie, dass das Kästchen Vegan jetzt nicht mehr ausgewählt ist, nachdem Sie die Auswahl des Kästchens Pak Choi aufgehoben haben?

Checkbox-Menü für Füllungen mit den Optionen: Füllungen Vegan Bok Choy Tofu & Shitake Meat Chicken Impossible Meat

Barrierefreiheit in Angular Material

Sie ersetzen das semantische Kontrollkästchen durch das Angular Material-Kontrollkästchen, das integriertes Wissen über dieses Interaktionsmuster enthält. Das Ersetzen von Komponenten durch Material-Komponenten garantiert nicht, dass die App barrierefrei ist. Wie bei jeder anderen Komponente müssen Sie manuell testen, da es viele Möglichkeiten gibt, Material nicht barrierefrei zu implementieren.

Kästchen durch Material-Kästchen ersetzen

  1. Fügen Sie zuerst die neue Liste mit Füllungen und eine Variable zum Speichern der ausgewählten Füllungsaromen hinzu:

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. Fügen Sie ein <mat-selection-list> hinzu, um diese unübersichtliche Gruppierung von HTML-Kästchen zu ersetzen:

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>

In den TODO-Kommentaren wird auch angezeigt, wo Sie nicht verwendeten Sass in src/app/shop/shop.component.scss entfernen können, um das Styling zu optimieren.

Änderungen bestätigen

Aktivieren Sie den Screenreader wieder und überprüfen Sie Ihre Änderungen. Die Kästchen sind jetzt auswählbar und lassen sich mit einem Screenreader intuitiver bedienen.

Checkbox-Menü für Füllungen mit den Elementen: Füllungen Bok Choy & Chili Crunch Tofu & Mushroom Chicken & Ginger Impossible Meat & Spinach Quantity

Prüfung der Barrierefreiheit:

  •  Alle Seiten haben eindeutige Seitentitel.
  •  Farben haben ein ausreichendes Kontrastverhältnis
  •  Semantisches HTML sorgt für logische Interaktion
  •  Alle Steuerelemente sind für Screenreader erreichbar.
  • 🛑 Screenreader liest keine Schiebereglerwerte vor
  • 🛑 Screenreader-Fokus im Farbwähler verlässt das Dialogfeld
  • 🛑 Änderungen, Fehler und Benachrichtigungen werden nicht angekündigt
  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

8. Steuerelement-Labels mit ARIA bereitstellen

Sie haben das semantische HTML und die Material-Komponenten Ihrer Angular-App geändert. Für einige Komponenten sind jedoch bestimmte Attribute erforderlich, damit Screenreader sie vollständig durchlaufen können.

Die WAI-ARIA-Spezifikation (Web Accessibility Initiative's Accessible Rich Internet Applications) hilft, Probleme zu beheben, die nicht mit nativem HTML behoben werden können. Damit können Sie Attribute angeben, die die Art und Weise ändern, wie ein Element in den Bedienungshilfenbaum übersetzt wird.

Am Ende dieses Abschnitts besteht Ihre App die folgende Prüfung:

  • 🛑 Screenreader liest keine Schiebereglerwerte vor

Sie finden die einzelnen Schritte unter den Kommentaren: TODO: #8. Provide control labels with ARIA.

Problem identifizieren

So finden Sie heraus, wo das Problem liegt:

  1. Aktivieren Sie VoiceOver.
  2. Rufen Sie den Schieberegler für die Menge auf und ändern Sie den Wert.
  3. Beachten Sie, dass das Wertlabel fehlt.

Chrome DevTools Lighthouse-Prüfungsergebnisse mit Fehler:  ARIA-Eingabefelder haben keine zugänglichen Namen Wenn ein Eingabefeld keinen barrierefreien Namen hat, wird es von Screenreadern mit einer allgemeinen Bezeichnung angesagt. Dadurch ist es für Nutzer, die auf Screenreader angewiesen sind, unbrauchbar. Weitere Informationen

ARIA-Attribute verwenden

Label-Kontrollgruppe mit aria-label bis <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>

Änderungen bestätigen

Aktivieren Sie den Screenreader wieder und überprüfen Sie Ihre Änderungen. Sie können den Schieberegler jetzt bewegen.

Chrome DevTools Lighthouse-Prüfung mit bestandener Prüfung für ARIA-Steuerelemente für Screenreader.

Prüfung der Barrierefreiheit:

  •  Alle Seiten haben eindeutige Seitentitel.
  •  Farben haben ein ausreichendes Kontrastverhältnis
  •  Semantisches HTML sorgt für logische Interaktion
  •  Alle Steuerelemente sind für Screenreader erreichbar.
  •  Für den Schieberegler wird ein Label mit ARIA-Attributen bereitgestellt.
  • 🛑 Screenreader-Fokus im Farbwähler verlässt das Dialogfeld
  • 🛑 Änderungen, Fehler und Benachrichtigungen werden nicht angekündigt
  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

9. Die Leistungsfähigkeit von @angular/cdk/a11y nutzen

Bisher haben Sie sich auf integrierte Angular-Tools verlassen, um häufige Probleme mit der Barrierefreiheit zu beheben. Sehen wir uns nun das A11y-Modul des CDK an und wie es uns helfen kann, kompliziertere und Angular-spezifische Probleme zu lösen.

Am Ende dieses Abschnitts setzen Sie den Kurs mit den Angular-A11Y-Modultools fort.

Sie finden diese Schritte im Kommentar: TODO: #9. Add the power of @angular/cdk/a11y.

Modul importieren

Fügen Sie das Modul Ihrer App hinzu:

src/app/app.module.ts

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

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

Was '@angular/cdk/a11y' macht

Das a11y-Modul bietet eine Reihe von Tools zur Verbesserung der Barrierefreiheit und ist besonders nützlich für Komponentenautoren.

In den folgenden Abschnitten fügen Sie drei gängige Dienste hinzu: FocusTrap, LiveAnnouncer und HighContrast.

Weitere Informationen zu allen anderen Diensten, die @angular/cdk/a11y bietet, finden Sie unter Bedienungshilfen.

10. Fokus mit FocusTrap steuern

Wenn ein Dialogfeld oder ein modales Fenster geöffnet ist, interagiert ein Nutzer nur darin. Wenn der Fokus außerhalb des Dialogfelds verschwindet, werden Kontexte vermischt und es entsteht ein Zustand, in dem der Nutzer nicht weiß, wo er sich auf der Seite befindet.

In Angular fängt die cdkTrapFocus-Direktive den tab--Tastenfokus innerhalb eines Elements ab. Diese Funktion soll verwendet werden, um barrierefreie Abläufe für Komponenten wie modale Dialogfelder zu erstellen, in denen der Fokus eingeschränkt werden muss.

Am Ende dieses Abschnitts besteht Ihre App die folgende Prüfung:

  • 🛑 Screenreader-Fokus im Farbwähler verlässt das Dialogfeld

Die Anleitung findest du in den Kommentaren: TODO: #10. Control focus with FocusTrap.

Problem identifizieren

Aktivieren Sie die Sprachausgabe und öffnen Sie das Dialogfeld zur Farbauswahl, um dieses Problem zu erkennen.

  1. Aktivieren Sie VoiceOver.
  2. Mit der Tabulatortaste können Sie die Farbe ändern.
  3. Prüfen Sie, ob die Fokusreihenfolge und das Fokussieren im Farbwähler intuitiv sind.

Website des Dumpling Time-Shops in einem lila und grünen Design mit einem geöffneten Dialogfeld zur Auswahl der Farbe der Dumpling-Verpackung

FocusTrap hinzufügen

Mit cdkFocusTrap lässt sich die Fokusreihenfolge in benutzerdefinierten Komponenten abfangen und steuern. Mit mat-dialog-content lassen sich die meisten Probleme beheben, indem der Fokus in einem Dialogfeld eingeschlossen wird. Fügen Sie das Attribut cdkFocusInitial hinzu, um den anfänglichen Fokusbereich für die Farbe des Dumpling-Wrappers <mat-selection-list> im Dialogfeld für die Farbauswahl zu definieren.

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>

Änderungen bestätigen

Aktivieren Sie den Screenreader wieder und überprüfen Sie Ihre Änderungen. Der Fokus wird jetzt im Dialogfeld auf Farbe ändern gesetzt.

Prüfung der Barrierefreiheit:

  •  Alle Seiten haben eindeutige Seitentitel.
  •  Farben haben ein ausreichendes Kontrastverhältnis
  •  Semantisches HTML sorgt für logische Interaktion
  •  Alle Steuerelemente sind für Screenreader erreichbar.
  •  Für den Schieberegler wird ein Label mit ARIA-Attributen bereitgestellt.
  •  Die Farbauswahl hat die richtige Fokusfixierung.
  • 🛑 Änderungen, Fehler und Benachrichtigungen werden nicht angekündigt
  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

11. Änderungen mit LiveAnnouncer ansagen lassen

Screenreader müssen benachrichtigt werden, wenn sich etwas auf der Seite ändert. Stellen Sie sich vor, Sie versuchen, ein Formular zu senden oder einen Kauf abzuschließen, und wissen nicht, dass ein Fehler aufgetreten ist, der das Senden des Formulars verhindert. Das ist frustrierend!

LiveAnnouncer wird verwendet, um Nachrichten für Nutzer von Screenreadern über eine aria-live-Region anzukündigen. So werden Screenreader über Benachrichtigungen und Änderungen auf Live-Seiten informiert. Weitere Informationen zu aria-live-Regionen finden Sie in WAI-ARIA des W3C. In Angular ist das Aufrufen von LiveAnnouncer als Dienst eine besser testbare Lösung als aria-live-Attribute.

Am Ende dieses Abschnitts besteht Ihre App die folgende Prüfung:

  • 🛑 Änderungen, Fehler und Benachrichtigungen werden nicht angekündigt

Die Anleitung findest du in den Kommentaren: TODO: #11. Announce changes with LiveAnnouncer.

Problem identifizieren

So können Sie das Problem identifizieren: Aktivieren Sie die Sprachausgabe und wählen Sie Kaufen aus, ohne die Formularfelder auszufüllen:

  1. Aktivieren Sie VoiceOver.
  2. Ändern Sie die Farbe und führen Sie einen Testkauf durch, indem Sie die Tab-Navigation verwenden.
  3. Beachten Sie, dass beim Schließen des Dialogfelds nicht angegeben wird, welche Farbe ausgewählt wurde, und der Kauf nicht gelesen wird.

Website des Dumpling Time-Shops in einem rosa und roten Design mit einem geöffneten Dialogfeld zur Auswahl der Farbe der Dumpling-Verpackung

LiveAnnouncer-Funktion in den Code einfügen

Füge LiveAnnouncer hinzu und gib sowohl die Farbauswahl als auch den gefälschten Kauf als String an. In einer echten Implementierung kann dies gelesen werden, wenn Sie zu einem Drittanbieter-Zahlungssystem navigieren oder wenn Formularfehler auftreten.

  1. Eine Mitteilung hinzufügen, wenn eine Farbe ausgewählt wird:

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. Eine Mitteilung hinzufügen, wenn ein gefälschter Kauf erfolgt:

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

Änderungen bestätigen

Aktivieren Sie den Screenreader wieder und überprüfen Sie Ihre Änderungen. Sie werden jetzt über Ihre Fehler benachrichtigt.

Prüfung der Barrierefreiheit:

  •  Alle Seiten haben eindeutige Seitentitel.
  •  Farben haben ein ausreichendes Kontrastverhältnis
  •  Semantisches HTML sorgt für logische Interaktion
  •  Alle Steuerelemente sind für Screenreader erreichbar.
  •  Für den Schieberegler wird ein Label mit ARIA-Attributen bereitgestellt.
  •  Die Farbauswahl hat die richtige Fokusfixierung.
  •  Änderungen, Fehler und Benachrichtigungen werden angekündigt
  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

12. Modus mit hohem Kontrast aktivieren

Microsoft Windows unterstützt eine Bedienungshilfe namens „Modus mit hohem Kontrast“. In diesem Modus wird das Erscheinungsbild aller Apps, einschließlich Web-Apps, so geändert, dass der Kontrast deutlich erhöht wird. In Angular möchten Sie die Einstellungen eines Nutzers in Ihrer App berücksichtigen.

Mit HighContrastModeDetector können Sie ermitteln, ob sich der Browser derzeit in einer Umgebung mit hohem Kontrast befindet.

Dieser Modus wird von Internet Explorer, Microsoft Edge und Firefox unterstützt. Google Chrome unterstützt den Windows-Modus mit hohem Kontrast nicht. Bei diesem Dienst wird der Modus mit hohem Kontrast, der von der Chrome-Browsererweiterung „Hoher Kontrast“ hinzugefügt wird, nicht erkannt.

Am Ende dieses Abschnitts besteht Ihre App die folgende Prüfung:

  • 🛑 Modus mit hohem Kontrast ist nicht aktiviert

Die Anleitung findest du in den Kommentaren: TODO: #12. Enable HighContrast mode.

Problem identifizieren

Um dieses Problem zu erkennen, öffnen Sie Ihre App in Internet Explorer, Microsoft Edge oder Firefox, aktivieren Sie den Modus mit hohem Kontrast und beobachten Sie, dass sich nichts ändert:

  1. Öffnen Sie Ihre App in Internet Explorer, Microsoft Edge oder Firefox.
  2. Aktivieren Sie den Modus mit hohem Kontrast.
  3. Die Anwendung ist unverändert.

Unterstützung für den Modus mit hohem Kontrast hinzufügen

Verwenden Sie in styles.scss den in @angular/cdk/a11y bereitgestellten cdk-high-contrast-Mixin, um Ihren Schaltflächen im Modus mit hohem Kontrast eine Kontur hinzuzufügen:

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

Änderungen bestätigen

Aktualisieren Sie die App und prüfen Sie die Änderungen. Sie haben der Schaltfläche im Modus mit hohem Kontrast eine Kontur hinzugefügt.

Die Website des Dumpling Time-Shops in Rot und Pink mit aktiviertem Modus mit hohem Kontrast. Die Schaltfläche „Kaufen“ ist jetzt mit einem dicken roten Rahmen deutlich hervorgehoben. Die Website des Dumpling Time-Shops in Blau und Grün mit aktiviertem Modus mit hohem Kontrast. Die Schaltfläche „Kaufen“ ist jetzt mit einem dicken blauen Rahmen deutlich hervorgehoben.

Prüfung der Barrierefreiheit:

  •  Alle Seiten haben eindeutige Seitentitel.
  •  Farben haben ein ausreichendes Kontrastverhältnis
  •  Semantisches HTML sorgt für logische Interaktion
  •  Alle Steuerelemente sind für Screenreader erreichbar.
  •  Für den Schieberegler wird ein Label mit ARIA-Attributen bereitgestellt.
  •  Die Farbauswahl hat die richtige Fokusfixierung.
  •  Änderungen, Fehler und Benachrichtigungen werden angekündigt
  •  Modus mit hohem Kontrast ist aktiviert

13. Glückwunsch!

Herzlichen Glückwunsch! Sie haben häufige Probleme mit der Web-Barrierefreiheit in Ihrer Angular-App behoben. 🎉

Alle Lösungen finden Sie im main-Branch.

Die Website des Dumpling Time-Shops in Rot und Pink zeigt alle Änderungen, die in diesem Codelab vorgenommen wurden. Die Website des Geschäfts „Dumpling Time“ mit blauem und grünem Design zeigt alle Änderungen, die in diesem Codelab vorgenommen wurden. Lighthouse-Prüfung in den Chrome-Entwicklertools mit einem Ergebnis von 100/100

Sie kennen jetzt die wichtigsten Schritte, die erforderlich sind, um acht häufige Barrierefreiheitsfehler in Ihrer Angular-Anwendung zu beheben.

Weitere Informationen

Sehen Sie sich diese Codelabs an:

Lesen Sie sich diese Materialien durch: