> WCAG-2.2-Muster auf Komponentenebene für Vue und Nuxt: Fokus in Modals und Teleport, Live-Regionen, Comboboxen, Lücken von axe-core und eine Teststufenleiter.
>
> Web page: https://balazscsorba.com/de/blog/vue-accessible-components · Language: Deutsch · Also available in: [English](https://balazscsorba.com/blog/vue-accessible-components.md) · [Magyar](https://balazscsorba.com/hu/blog/vue-accessible-components.md)
> Author: Balázs Csorba · Published: 2026-10-02 · Keywords: accessible vue components, vue accessibility wcag 2.2, vue focus management modal, aria-live vue async, reka ui accessibility, eslint-plugin-vuejs-accessibility, axe-core playwright vue, vue combobox accessibility, wcag target size 24px, spa route change announcement accessibility

[Blog](https://balazscsorba.com/de/blog)/Web-Engineering

# Barrierefreie Vue-Komponenten: die WCAG-2.2-Muster, die automatisierte Tests übersehen

WCAG-2.2-Muster auf Komponentenebene für Vue und Nuxt: Fokus in Modals und Teleport, Live-Regionen, Comboboxen, Lücken von axe-core und eine Teststufenleiter.

[Balázs Csorba](https://balazscsorba.com/de/about)·2\. Oktober 2026·12 Min. Lesezeit

-   Vue accessibility
-   WCAG 2.2
-   Focus management
-   Live regions
-   Component testing

![Ein Dialog mit Fokusrahmen um einen Button, daneben Tab-Taste und Lautsprecher.](https://balazscsorba.com/images/blog/vue-accessible-components/cover.webp?v=39acedf83b)

## Das Wichtigste in Kürze

-   Fünf der neun neuen Kriterien von WCAG 2.2 betreffen den Komponentencode direkt: Fokus nicht verdeckt, Ziehbewegungen, Zielgröße, redundante Eingaben und zugängliche Authentifizierung.
-   axe-core findet im Schnitt 57 % der WCAG-Probleme automatisch, und seine einzige Regel für WCAG 2.2 ist standardmäßig deaktiviert; ein grüner Scan belegt also keine Qualität für Tastatur oder Screenreader.
-   Die Fokusverwaltung gehört in die Komponente: Ein natives Dialogelement mit inertem Hintergrund ist die günstigere Basis, und Routenwechsel in Single-Page-Anwendungen brauchen eine ausdrückliche Fokusverschiebung.
-   Live-Regionen müssen existieren, bevor sie sich ändern, und nur Klartext enthalten; gestreamte KI-Ausgaben sollten in satzgroßen Stücken angesagt werden statt Token für Token.
-   Testen Sie in einer Leiter von Lint und Komponenten-Scans bis zu ARIA-Snapshots und einer manuellen Screenreader-Prüfung, und schreiben Sie die Definition of Done auf, damit das Review sie durchsetzen kann.

Auf dieser Seite

1.  [Welche WCAG-2.2-Kriterien betreffen den Komponentencode?](https://balazscsorba.com/#wcag-criteria-in-component-code)
2.  [Was deckt axe-core tatsächlich ab?](https://balazscsorba.com/#what-axe-actually-covers)
3.  [Wie sich der Fokus bei Modals, Teleport und Routenwechseln verhalten sollte](https://balazscsorba.com/#focus-management-modals-teleport-and-route-changes)
4.  [Wie verhalten sich asynchrone Updates und Live-Regionen?](https://balazscsorba.com/#async-ui-and-live-regions)
5.  [Sollten Sie eine eigene Auswahl oder Combobox bauen?](https://balazscsorba.com/#custom-selects-comboboxes-and-when-not-to-build-one)
6.  [Was lassen headless-Bibliotheken trotzdem bei Ihnen?](https://balazscsorba.com/#headless-libraries-what-they-still-dont-own)
7.  [Wie testen Sie das alles?](https://balazscsorba.com/#the-testing-ladder)
8.  [Was gehört zur Definition of Done einer Komponente?](https://balazscsorba.com/#component-definition-of-done-checklist)
9.  [Quellen](https://balazscsorba.com/#sources)

Diesen Artikel anhören

0:000:00

**Die meisten Barrierefreiheitsfehler in einer Vue-App sind Komponentenfehler.** Ein Dialog, der den Fokus nicht zurückgibt, ein Toast, den ein Screenreader nie ansagt, eine Combobox, die auf die Pfeiltasten nicht reagiert, ein Symbolbutton mit 16 Pixeln Kantenlänge: Jeder dieser Fehler wird einmal in einer gemeinsamen Komponente geschrieben und dann auf jeder Seite ausgeliefert, die sie verwendet. Deshalb sind Komponenten die richtige Einheit für Barrierefreiheit und der richtige Ort, um die Regeln festzuhalten.

Dieser Artikel ist die technische Hälfte von WCAG 2.2 für Vue und Nuxt. Er ordnet die Erfolgskriterien zu, die in Komponentencode landen, erklärt, was axe-core sehen kann und was nicht, behandelt Fokusverwaltung, asynchrone Live-Regionen und eigene Comboboxen und endet mit einer Teststufenleiter und einer Definition of Done, die Sie in eine Vorlage für Pull Requests übernehmen können. Ob eine Website konform ist, entscheidet er nicht; den rechtlichen Rahmen beschreibt [der European Accessibility Act für B2B-Shops](https://balazscsorba.com/de/blog/european-accessibility-act-b2b-shop).

## Welche WCAG-2.2-Kriterien betreffen den Komponentencode?

Fünf der neun Kriterien, die [WCAG 2.2](https://www.w3.org/TR/WCAG22/) als neu kennzeichnet, betreffen den Komponentencode direkt: 2.4.11 Fokus nicht verdeckt, 2.5.7 Ziehbewegungen, 2.5.8 Zielgröße (Minimum), 3.3.7 Redundante Eingaben und 3.3.8 Zugängliche Authentifizierung (Minimum). Die älteren Kriterien, die am häufigsten scheitern, bleiben 2.4.7 Fokus sichtbar sowie die Kontrastkriterien 1.4.3 und 1.4.11. Sie haben sich in Version 2.2 nicht geändert, stecken aber in jedem eigenen Design.

Jedes Kriterium entspricht einem bestimmten Vue-Artefakt. Fokus nicht verdeckt bedeutet meist, dass ein fixierter Header, eine Cookie-Leiste oder ein schwebendes Chat-Widget die fokussierte Zeile oder Schaltfläche überdeckt. Die Zielgröße betrifft reine Symbol-Schließen-Buttons und Werkzeugleisten, deren Trefferfläche kleiner als 24 × 24 CSS-Pixel ist. Ziehbewegungen betreffen sortierbare Listen und Schieberegler, die eine Alternative mit einem einzelnen Zeiger brauchen, etwa Schaltflächen. Redundante Eingaben treffen mehrstufige Formulare, die eine Adresse erneut abfragen, die der Nutzer zwei Schritte zuvor schon eingegeben hat. Zugängliche Authentifizierung betrifft Anmeldemasken und Einmalcode-Felder, die Einfügen oder Passwortmanager blockieren.

Die Tabelle ist die Arbeitskarte: eine Zeile je Kriterium, das Vue-Artefakt, in dem es auftaucht, ob axe-core dafür heute eine Regel hat, und die günstigste Korrektur.

Kriterium

Vue-Artefakt

axe-Regel heute

Günstigste Korrektur

2.4.7 Fokus sichtbar (AA)

Fokusstile eigener Bedienelemente

keine

nativen Rahmen behalten; ersetzen, nie nur entfernen

2.4.11 Fokus nicht verdeckt (AA)

fixierter Header, Cookie-Leiste, Chat-Widget

keine

scroll-margin für Fokusziele

2.5.7 Ziehbewegungen (AA)

sortierbare Listen, Schieberegler

keine

Schaltflächen, die Elemente verschieben

2.5.8 Zielgröße (AA)

reine Symbol-Schließen- und Werkzeugleisten-Buttons

target-size, standardmäßig aus

Trefferfläche von 24 × 24 px

3.3.7 Redundante Eingaben (A)

mehrstufige Checkout- und Adressformulare

keine

aus früheren Schritten vorbefüllen

3.3.8 Zugängliche Authentifizierung (AA)

Anmelde-, OTP- und Passwortfelder

keine

Einfügen und Passwortmanager erlauben

1.4.3 und 1.4.11 Kontrast

Design-Tokens, Rahmen, Fokusrahmen

nur Text (color-contrast)

jedes Token-Paar in jedem Zustand prüfen

4.1.2 Name, Rolle, Wert

eigene Comboboxen, Symbol-Buttons

teilweise

zuerst das native Element verwenden

## Was deckt axe-core tatsächlich ab?

Automatisierte Scanner finden einen brauchbaren Teil der WCAG-Probleme, aber selten die, die einen Tastatur- oder Screenreader-Nutzer typischerweise ausbremsen. axe-core gibt an, im Schnitt 57 % der WCAG-Probleme automatisch zu finden. Der WCAG-2.2-Abschnitt enthält eine einzige Regel, target-size, und die ist standardmäßig deaktiviert.

Die [README von axe-core](https://github.com/dequelabs/axe-core) nennt die Obergrenze deutlich: „With axe-core, you can find on average 57% of WCAG issues automatically.“ Die [Regelbeschreibungen](https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md) bestätigen die Lücke bei WCAG 2.2: Die einzige 2.2-Regel ist target-size, deaktiviert, bis WCAG 2.2 breiter verbreitet ist. Keine Regel prüft Fokus nicht verdeckt, redundante Eingaben oder zugängliche Authentifizierung.

Die Bevölkerungsdaten zeigen, dass die Lücke messbar ist. Der [Million-Report von WebAIM 2026](https://webaim.org/projects/million/) hat eine Million Startseiten untersucht und im Schnitt 56,1 erkannte Fehler pro Seite gefunden, 10,1 % mehr als 2025 mit 51. Startseiten mit Vue.js kamen auf durchschnittlich 64,6, Nuxt.js-Seiten auf 54,7 erkannte Fehler. WebAIM stellt klar, dass nicht alle Konformitätsverstöße automatisch erkannt werden können; diese Werte zeigen also, was die Werkzeuge sehen, und sind kein Urteil über eine einzelne Website.

**Ein grüner Scan ist kein Bestanden**

Behandeln Sie einen automatisierten Scan als Alarm für die Fehler, die er benennen kann. Tastaturreihenfolge, Fokusverhalten und Ansagen des Screenreaders brauchen einen Menschen; die Teststufenleiter weiter unten ordnet jede Fehlerklasse der Stufe zu, die sie finden kann.

## Wie sich der Fokus bei Modals, Teleport und Routenwechseln verhalten sollte

Ein Modal muss den Fokus beim Öffnen hineinholen, Tab und Umschalt+Tab darin halten, mit Escape schließen und den Fokus zu dem Element zurückgeben, das es geöffnet hat. Eine selbst gebaute Fokusfalle kann alle vier Aufgaben erfüllen, aber ein natives Dialogelement, dessen restliche Seite inert markiert ist, erledigt den größten Teil mit weniger Code.

Selbst gebaute Fallen scheitern meist an drei Stellen. Sie sammeln fokussierbare Elemente einmal beim Mounten, daher wird ein später gerendertes Feld übersprungen. Sie begrenzen sich auf den Container, in dem die Komponente geschrieben wurde, aber Teleport verschiebt den DOM-Knoten des Dialogs an eine andere Stelle im Dokument, also verfehlt die Falle ihn. Und sie geben den Fokus an einen Button zurück, den ein erneutes Rendern bereits entfernt hat, sodass der Fokus auf body zurückfällt.

Die günstigere Basis ist das native Dialogelement. Ein Aufruf von `showModal()` setzt das Element in die Top Layer, macht den Rest des Dokuments inert und schließt mit Escape. Aktuelle Engines geben den Fokus beim Schließen ebenfalls an den Auslöser zurück, doch die Details der Rückgabe unterscheiden sich zwischen den Implementierungen; schreiben Sie dafür also einen Test in jedem Browser, den Sie ausliefern. Wo ein natives Dialogelement nicht passt, erzielt das Attribut `inert` denselben Effekt auf der Seite hinter einem eigenen Overlay.

![Fokuslebenszyklus eines teleportierten Dialogs Fünf Schritte von links nach rechts: Der Auslöser öffnet den Dialog, und der Fokus wandert zu seinem ersten Bedienelement; Tab und Umschalt+Tab bleiben im Dialog; Escape oder der Schließen-Button schließt ihn; danach kehrt der Fokus zu dem Element zurück, das ihn geöffnet hat.](https://balazscsorba.com/images/blog/vue-accessible-components/diagram-16.webp?v=004deddda0)

Fokuslebenszyklus eines teleportierten Dialogs: Öffnen über den Auslöser, Fokus hinein, Tab bleibt darin, Schließen mit Escape oder dem Schließen-Button, Fokus zurück zum Auslöser.

### Routenwechsel in Vue Router und Nuxt

Eine Navigation in einer Single-Page-Anwendung lädt das Dokument nicht neu; der Browser verschiebt den Fokus also nicht und kündigt die neue Seite nicht an. Der [Barrierefreiheitsleitfaden von Vue](https://vuejs.org/guide/best-practices/accessibility.html) behandelt das mit einem Skip-Link als erstem fokussierbaren Element und einem Watcher auf `route.path`, der den Fokus nach jedem Routenwechsel verschiebt. Das hier verwendete Sentinel-Muster legt eine fokussierbare Überschrift an den Anfang des Hauptbereichs, die das Layout nach der Navigation fokussiert. Ein Fokus auf Überschrift oder Sentinel funktioniert besser als ein Fokus auf `body`, denn `body` ist für einen Screenreader kein sinnvoller Startpunkt.

```
<!-- Layout sketch: move focus to the page heading after each route change -->
<script setup lang="ts">
const route = useRoute()
const sentinel = ref<HTMLElement | null>(null)

watch(() => route.path, async () => {
  await nextTick() // let the new page render first
  sentinel.value?.focus()
})
</script>

<template>
  <main>
    <h1 ref="sentinel" tabindex="-1"><slot name="title" /></h1>
    <slot />
  </main>
</template>
```

Kombinieren Sie die Fokusverschiebung nur dann mit einer Ansage, wenn die fokussierte Überschrift dem Nutzer nicht ohnehin zeigt, wo er ist. Ob ein geänderter Dokumenttitel allein angesagt wird, hängt von Screenreader und Browser ab; testen Sie diese Kombination, statt sie vorauszusetzen.

## Wie verhalten sich asynchrone Updates und Live-Regionen?

Eine Live-Region kündigt eine Änderung nur an, wenn sie vor der Änderung schon existierte. Rendern Sie den Container mit der Seite und aktualisieren Sie danach seinen Text. Verwenden Sie standardmäßig polite, assertive nur für Fehler, die den Nutzer blockieren, und legen Sie nie Bedienelemente in die Region, denn Live-Regionen werden als Klartext angesagt.

Die [MDN-Anleitung zu Live-Regionen](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions) läuft auf dieselben Regeln hinaus: die Region zuerst etablieren, die erste inhaltliche Aktualisierung auf einen späteren Task verschieben und assertive nur für dringende Meldungen verwenden. Sie warnt außerdem, dass Live-Regionen in der Regel als reiner Text angesagt werden, sodass Links, Schaltflächen und andere Semantik im aktualisierten Inhalt womöglich nicht übermittelt werden.

Hier bricht die Fehlermeldung mit Toasts. Mountet eine Komponente den Toast zusammen mit seiner Live-Region, erscheinen Region und Meldung im selben DOM-Update, und viele Screenreader sagen die Meldung dann nicht an. Die Lösung ist eine Region, die mit der Seite gerendert wird, vorhanden, aber leer, und in die die Komponente den Toast-Text schreibt. Dasselbe gilt für Zusammenfassungen der Eingabeprüfung und für Speicherbestätigungen nach einem Routenwechsel.

Gestreamte Ausgaben sind der schwierigste Fall. Schreibt jeder Chunk einer LLM-Antwort in eine höfliche Region, liest der Screenreader die Antwort Wort für Wort vor und unterbricht sich ständig. Halten Sie den sichtbaren Text während des Streamings aktuell, und kündigen Sie eine Zusammenfassung oder die fertige Antwort an Satzgrenzen oder am Ende an. Der [Beitrag zur Barrierefreiheit von Streaming-Chats](https://balazscsorba.com/de/blog/vue-ai-chat-ui-streaming-accessibility) behandelt die chatspezifischen Details.

## Sollten Sie eine eigene Auswahl oder Combobox bauen?

Verwenden Sie ein natives select, wann immer das Design es erlaubt. Bauen Sie eine eigene Combobox nur, wenn das Produkt etwas braucht, das ein natives Element nicht kann, und besitzen Sie dann den vollständigen Tastaturvertrag aus dem [WAI-ARIA Authoring Practices Guide (APG)](https://www.w3.org/WAI/ARIA/apg/practices/).

Die APG benennt den Preis klar: „Unlike native HTML form elements, browsers do not provide keyboard support for graphical user interface (GUI) components that are made accessible with ARIA; authors have to provide the keyboard support in their code.“ Bei einer Combobox heißt das: Pfeiltasten bewegen sich durch die Optionen, Enter wählt aus, Escape schließt, Tippen filtert die Liste, und der Fokus bleibt dort, wo das Muster ihn vorsieht. Die APG führt Combobox, Listbox, Dialog, Grid, Karussell und Akkordeon als eigene Muster mit eigenen Verträgen, und Teams verwechseln sie oft.

Zwei Umsetzungsentscheidungen sind wichtig. `aria-activedescendant` lässt den DOM-Fokus im Texteingabefeld und verweist per id auf die markierte Option; das passt zu filterbaren Comboboxen. Ein Roving Tabindex verschiebt den echten Fokus zwischen den Elementen, das passt zu Werkzeugleisten, Menüs und Grids. Entscheiden Sie nach dem, worin der Nutzer tippt: Ein Textfeld spricht für activedescendant, eine Reihe von Bedienelementen für ein Roving Tabindex.

Eine eigene Steuerung ist dauerhafte Wartung. Jedes Framework-Upgrade, jeder neue Optionstyp und jede Designänderung kann den Vertrag brechen, und der Komponententest muss die Tastatur durchspielen, nicht nur das gerenderte Markup. Erfüllt ein natives select mit gestylter Hülle die Anforderung, ist das fast immer die günstigere Komponente.

## Was lassen headless-Bibliotheken trotzdem bei Ihnen?

Headless-Komponentenbibliotheken liefern die ARIA-Verdrahtung, die Tastaturbelegung und den Fokusbereich eines Musters. Sie liefern nicht Ihre zugänglichen Namen, Ihren Farbkontrast, Ihre Fehlermeldungen oder die Zielgröße Ihrer Symbolbuttons. [Reka UI](https://reka-ui.com/docs/overview/introduction) ist im Oktober 2026 eine der Vue-Optionen, und ihre Dokumentation sagt deutlich, was sie abdeckt.

Reka UI bezeichnet sich als v2-Weiterentwicklung von Radix Vue und sagt, seine Komponenten folgen den WAI-ARIA-Designmustern und übernehmen Details wie aria-Attribute, Tastaturnavigation und Fokusverwaltung. Den Rest des Vertrags behält das Team, dem das Produkt gehört. Die Liste unten ist das, was bei jedem headless Aufbau bei Ihnen bleibt:

-   **Zugängliche Namen:** Ein Symbolbutton, der den Warenkorb schließt, braucht einen Namen wie „Warenkorb schließen“; eine Bibliothek kann nicht erraten, was ein nacktes Symbol bedeutet.
-   **Kontrast im eigenen Design:** Die Bibliothek liefert keine Farben; jedes Token-Paar muss in Hell, Dunkel und jedem Zustand geprüft werden.
-   **Fehlermeldungen:** Der Fehlertext muss über `aria-describedby` mit seinem Feld verbunden sein und sagen, was als Nächstes zu tun ist.
-   **Ansagen bei Routenwechseln:** Seitenwechsel in einer Single-Page-Anwendung liegen bei Ihnen, wie oben beschrieben.
-   **Zielgröße:** Ein headless Button hat die Größe, die Ihr CSS ihm gibt.

## Wie testen Sie das alles?

Testen Sie in Stufen, die günstigste zuerst: Templates linten, jede Komponente in Unit-Tests scannen, echte Abläufe Ende zu Ende scannen, den Barrierefreiheitsbaum mit ARIA-Snapshots prüfen und mit einer manuellen Prüfung per Tastatur und Screenreader abschließen. Jede Stufe findet Fehlerklassen, die die Stufen davor nicht finden, und die oberste Stufe braucht weiterhin einen Menschen.

![Die Teststufenleiter Fünf Stufen von links nach rechts: Template-Lint-Regeln, ein axe-Scan auf Komponentenebene in Unit-Tests, ein axe-Scan echter Abläufe Ende zu Ende, ein ARIA-Snapshot, der den Barrierefreiheitsbaum prüft, und eine manuelle Prüfung mit Tastatur und Screenreader.](https://balazscsorba.com/images/blog/vue-accessible-components/diagram-37.webp?v=4c6e41c627)

Die Teststufenleiter, günstigste zuerst: Jede Stufe findet Fehlerklassen, die die Stufen davor nicht finden, und die oberste Stufe braucht weiterhin einen Menschen mit Screenreader.

Lint kommt zuerst, weil die günstigsten Fehler die sind, die ein Template sichtbar macht. eslint-plugin-vuejs-accessibility markiert typische Template-Fehler wie fehlende Alternativtexte und ungültige ARIA-Attribute. Ob ein Alternativtext sinnvoll ist, kann das Plugin nicht beurteilen; es ist ein Filter, kein Urteil.

Unit-Tests führen axe-core für jede Komponente isoliert aus, sodass ein Fehler auf eine Komponente zeigt.

```
// Vitest: scan the rendered dialog, not the whole page
import axe from 'axe-core'

it('confirm dialog has no detectable violations', async () => {
  const { container } = render(ConfirmDialog, { props: { open: true } })
  const results = await axe.run(container)
  expect(results.violations).toEqual([])
})
```

Die Ende-zu-Ende-Stufe führt `@axe-core/playwright` über echte Abläufe aus: Dialog öffnen, Formular mit einem Fehler absenden, dann den Zustand scannen, den der Nutzer tatsächlich erreicht. Der [Playwright-Leitfaden zur Barrierefreiheit](https://playwright.dev/docs/accessibility-testing) empfiehlt diese Kombination und sagt deutlich, dass viele Probleme nur manuell zu finden sind. Playwright hat außerdem `toMatchAriaSnapshot` seit Version 1.49, das den [Barrierefreiheitsbaum prüft](https://playwright.dev/docs/api/class-locatorassertions); eine Schaltfläche, die still ihren Namen verliert, lässt einen Test scheitern, den ein visueller Snapshot übersähe.

```
// Playwright: scan the state a user reaches, not the empty page
import AxeBuilder from '@axe-core/playwright'

await page.getByRole('button', { name: 'Delete order' }).click()
const results = await new AxeBuilder({ page }).include('[role="dialog"]').analyze()
expect(results.violations).toEqual([])
```

Die oberste Stufe ist ein Mensch mit Screenreader. Die [WebAIM Screen Reader User Survey #11](https://webaim.org/projects/screenreadersurvey11/), erhoben im Juli und August 2026 mit 1.780 Antworten, nennt JAWS als primären Desktop-Screenreader für 55,0 % der Befragten, NVDA für 32,9 % und VoiceOver für 6,5 %. Testen Sie als Basis mit NVDA unter Windows und VoiceOver unter macOS und iOS, und nehmen Sie JAWS hinzu, wenn Ihre Nutzer es verwenden. Gehen Sie zuerst den ganzen Ablauf nur mit der Tastatur durch, denn die meisten Fokusfehler zeigen sich, bevor ein Screenreader läuft. Den zweiten Durchgang führe ich mit dem Playwright-MCP-Server aus einer Agentensitzung aus, sodass der Agent den Dialog öffnet, durchtabt und den Scan startet; die Ansagen hört aber weiterhin ein Mensch.

Für die Entwicklung läuft [@nuxt/a11y](https://github.com/nuxt/a11y) axe-core in den Nuxt DevTools mit routenbewusstem Scannen und kann Berichte beim `nuxt generate` erzeugen. Die neueste Version ist noch 1.0.0-alpha.1; nutzen Sie es daher als Entwicklungshilfe und halten Sie das CI-Gate in den oben genannten Stufen. Dieselbe Disziplin gilt wie bei [Nuxt Core Web Vitals und Performance-Budgets](https://balazscsorba.com/de/blog/nuxt-core-web-vitals-performance): Eine Zahl, die in der CI geprüft wird, bleibt wahr; eine Zahl, die einmal geprüft wird, nicht.

## Was gehört zur Definition of Done einer Komponente?

Eine Komponente ist fertig, wenn Name, Rolle, Tastaturverhalten, Fokusbehandlung, Kontrast, Zielgröße und Verhalten der Live-Region je geprüft und im Review festgehalten sind. Die Liste unten ist so geschrieben, dass sie in eine Vorlage für Pull Requests oder in einen Review-Skill passt, und jeder Punkt entspricht einer Stufe der Leiter.

-   **Name und Rolle:** Jedes Bedienelement hat einen zugänglichen Namen, und seine Rolle passt zu einem nativen Element oder zum APG-Muster, das es umsetzt.
-   **Tastatur:** Jede Aktion funktioniert mit den Tasten, die das Muster vorsieht; außerhalb von Dialogen gibt es keine Fokusfalle.
-   **Fokus:** Der Fokusindikator ist in hellen und dunklen Themes sichtbar, wird an seiner Scrollposition nicht von fixierten Elementen verdeckt und kehrt nach dem Schließen oder Navigieren zum Auslöser zurück.
-   **Kontrast:** Text erreicht 4,5:1, erforderliche visuelle Zustände erreichen 3:1, in hellen und dunklen Themes.
-   **Zielgröße:** Zeigerziele sind mindestens 24 × 24 CSS-Pixel groß oder so weit auseinander, dass eine Ausnahme greift.
-   **Live-Regionen:** Die Region existiert vor der Änderung, ist höflich, außer die Meldung blockiert den Nutzer, und enthält nur Klartext.
-   **Formulare:** Fehler sind ihren Feldern zugeordnet und hängen nicht allein an der Farbe, redundante Eingaben sind vorbefüllt, und Authentifizierungsfelder erlauben Einfügen und Passwortmanager.
-   **Ziehen:** Jede Zieh-Aktion hat eine Alternative mit einem einzelnen Zeiger.
-   **Bewegung:** Übergänge mit Bedeutung respektieren `prefers-reduced-motion`.
-   **Rechts-nach-links:** Fokusindikator und Symbolrichtung funktionieren in rechts-nach-links-Layouts.

Sobald die Liste festgehalten ist, kann ein Review-Agent neue Komponenten dagegen prüfen, bevor ein Mensch den Diff liest; die Screenreader-Prüfung bleibt bei einem Menschen. Ich pflege etwa 20 Agenten-Skills in `~/.agents/skills`, und diese Checkliste ist ein naheliegender Kandidat dafür. Wenn Sie eine Vue- oder Nuxt-Komponentenbibliothek bauen oder prüfen und dies in die CI einbinden möchten, sehen Sie sich meine [Vue- und Nuxt-Arbeit](https://balazscsorba.com/de/expertise/vue-nuxt-developer) an.

## Quellen

1.  [W3C: Web Content Accessibility Guidelines (WCAG) 2.2](https://www.w3.org/TR/WCAG22/)
2.  [axe-core README (Deque)](https://github.com/dequelabs/axe-core)
3.  [axe-core rule descriptions](https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md)
4.  [WebAIM: The WebAIM Million 2026](https://webaim.org/projects/million/)
5.  [WebAIM: Screen Reader User Survey #11](https://webaim.org/projects/screenreadersurvey11/)
6.  [Vue: accessibility guide](https://vuejs.org/guide/best-practices/accessibility.html)
7.  [WAI-ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/practices/)
8.  [MDN: ARIA live regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions)
9.  [Playwright: accessibility testing](https://playwright.dev/docs/accessibility-testing)
10.  [Playwright: locator assertions (toMatchAriaSnapshot)](https://playwright.dev/docs/api/class-locatorassertions)
11.  [nuxt/a11y on GitHub](https://github.com/nuxt/a11y)
12.  [Reka UI: introduction](https://reka-ui.com/docs/overview/introduction)

## Häufige Fragen

Macht axe-core eine Vue-App barrierefrei?

Nein. axe-core findet nach eigenen Angaben im Schnitt 57 % der WCAG-Probleme automatisch, und die WCAG-2.2-Regel ist standardmäßig deaktiviert. Tastatur-, Fokus- und Screenreader-Verhalten muss weiterhin manuell geprüft werden.

Welche WCAG-2.2-Kriterien betreffen Vue-Komponenten am stärksten?

Fokus nicht verdeckt, Ziehbewegungen, Zielgröße (Minimum), redundante Eingaben und zugängliche Authentifizierung (Minimum) betreffen den Komponentencode direkt. Fokus sichtbar und die Kontrastkriterien sind älter, scheitern bei eigenem Styling aber genauso häufig.

Wie behandle ich den Fokus in einem Modal, das Teleport verwendet?

Verwenden Sie ein natives Dialogelement, das mit showModal() geöffnet wird, setzen Sie den Hintergrund bei Bedarf auf inert und testen Sie die Fokusrückgabe nach dem Schließen. Eine selbst gebaute Falle, die innerhalb ihres ursprünglichen Elternelements sucht, übersieht den teleportierten Dialog.

Warum werden meine Ansagen des Screenreaders nicht vorgelesen?

Oft wurde die Live-Region im selben Update erzeugt wie ihre Meldung. Rendern Sie die Region zuerst mit der Seite, lassen Sie sie vorhanden, aber leer, und schreiben Sie die Meldung danach hinein.

Sollte ich eine eigene Combobox oder ein natives select verwenden?

Nehmen Sie ein natives select, außer das Produkt braucht Verhalten, das es nicht bieten kann. Eine eigene Combobox bedeutet, den APG-Tastaturvertrag zu besitzen und ihn bei jedem Upgrade funktionsfähig zu halten.

Geschrieben von Balázs Csorba

Senior Fullstack & AI Engineer in der Steiermark – über 10 Jahre Vue, Nuxt, Node.js und PHP, heute baue ich Werkzeuge für KI-Agenten.

[Vue.js- & Nuxt-Entwicklung →](https://balazscsorba.com/de/expertise/vue-nuxt-developer)[Über mich →](https://balazscsorba.com/de/about)

## Weitere Artikel

-   [Schema.org-Strukturdaten für B2B-Shops: Preise hinter Logins, Einheiten und Varianten](https://balazscsorba.com/de/blog/schema-org-structured-data-b2b-shop)
-   [Ein KI-Assistent für den Support im B2B-Shop: Tools, Berechtigungen und die Übergabe an Menschen](https://balazscsorba.com/de/blog/ai-assistant-b2b-shop-customer-support)
-   [Streaming-Chat mit KI in Vue und Nuxt: von Anfang an barrierefrei](https://balazscsorba.com/de/blog/vue-ai-chat-ui-streaming-accessibility)
-   [Eine LLM-Übersetzungspipeline für i18n: Glossar, Platzhalter und Review](https://balazscsorba.com/de/blog/llm-translation-pipeline-i18n)

## Klingt nach dem, was du suchst?

Erzähl mir von deinem Projekt oder deiner Stelle – ich freue mich, von dir zu hören.

[Kontakt aufnehmen](mailto:contact@balazscsorba.com) [Auf LinkedIn vernetzen](https://www.linkedin.com/in/balazs-csorba)
