Umfrage zu barrierefreien Komponentenbibliotheken
Welche bestehen tatsächlich ein axe-Audit
Wir haben sieben der meistgeladenen React-Komponentenbibliotheken aus dem Jahr 2026 installiert, jede in ein frisches Next.js-15-/React-19-/TypeScript-Projekt eingebunden und denselben Audit-Prozess gegen jedes Primitiv angewendet: axe-core 4.11 in Headless Chromium, manuelle Tastatur-Sweeps, NVDA unter Windows, VoiceOver unter macOS und einen Lighthouse-Accessibility-Durchlauf für die Bundle-Größe.
1. Das Audit-Framework
Jede Bibliothek wurde in dasselbe React-19-/Next.js-15-/TypeScript-5.5-Gerüst installiert, dabei der jeweils vom Hersteller empfohlene Installationspfad verwendet: npm i für die paketierten Bibliotheken (Radix-UI-Primitive, Headless UI 2.x, Mantine 8.x, Chakra UI v3, Ark UI, React Aria Components) sowie die shadcn-CLI für shadcn/ui — die den Quellcode in components/ui kopiert, anstatt ein Paket einzubinden. Anschließend wurde eine Kitchen-Sink-Demo-Seite aufgebaut, die alle interaktiven Primitive der jeweiligen Bibliothek in ihrem Standard-Zustand ohne Theme-Überschreibungen und ohne eigene Wrapper exponiert.
Das Audit-Framework lief in drei Durchgängen. Der erste Durchgang war ein automatisierter axe-core-4.11-Scan per Playwright gegen das gerenderte DOM, mit dem vollständigen WCAG-2.2-AA-Regelwerk und den experimentellen Regeln aktiviert. Der zweite Durchgang war ein manueller Tastatur-Sweep: Tab, Shift+Tab, Pfeiltasten, Escape, Enter, Leertaste sowie Pos1/Ende gegen jedes Primitiv, bewertet am erwarteten Tastaturverhalten des WAI-ARIA Authoring Practices Guide. Der dritte Durchgang war ein Screenreader-Rauchtest mit NVDA 2025.1 unter Chrome und Safari/VoiceOver unter macOS Sonoma, mit Fokus auf Rollenansage, zugänglichem Namen und Zustandsmeldung bei Interaktion.
Elf ARIA-Muster wurden als Testfläche für die Matrix ausgewählt, weil dies genau jene Muster sind, die in Produkt-UIs auftauchen, gegen die geklagt wird: Dialog, Alert-Dialog, Combobox, Listbox, Menü, Menüleiste, Tabs, Akkordeon, Tooltip, Switch und Slider. Eine Bibliothek, die Schaltflächen und Überschriften korrekt implementiert, aber eine fehlerhafte Combobox liefert, ist eine Bibliothek, die beim ersten Audit scheitert, sobald ein echter Nutzer versucht, eine Kundenliste zu filtern.
Ein axe-Bestehen bedeutet null Verstöße gegen eine Regel aus dem WCAG-2.2-AA-Tag sowie dem experimentellen Tag, gerendert mit Standard-Props und dem dokumentierten Verwendungsbeispiel der Bibliothek. Das bedeutet nicht, dass die Bibliothek hieb- und stichfest ist — axe erkennt etwa die Hälfte aller WCAG-Verstöße — aber eine Bibliothek, die axe in ihrer eigenen Demo nicht besteht, kann ihn nirgendwo sonst bestehen.
„Der Standard-Zustand ist der einzige Zustand, den die meisten Engineering-Teams je zu Gesicht bekommen. Liefert eine Bibliothek einen fehlerhaften Standard, gelangt dieser fehlerhafte Standard in die Produktion.“
2. Sieben Bibliotheken im Vergleich
Drei der sieben Bibliotheken — Radix UI, React Aria Components und Ark UI — bestanden axe bei jedem Primitiv im Standard-Zustand ohne jegliche Überschreibung. Headless UI bestand alle außer dem Menü-Primitiv, bei dem ein fehlendes aria-activedescendant am Listbox-artigen Menü-Trigger einen einzelnen Verstoß auslöste. shadcn/ui — selbst eine dünne Schicht über Radix UI — bestand bei jedem der gelieferten Primitive, aber der Haken ist, dass es nur etwa zwei Drittel der Radix-Fläche abdeckt und die Lücken (Combobox, Listbox, Menüleiste) genau die Muster sind, bei denen Anbieter bei eigener Implementierung am häufigsten Barrierefreiheitsfehler einbauen.
Mantine und Chakra UI v3 waren die beiden Bibliotheken, deren Standardkonfiguration axe-Verstöße erzeugte. Die Combobox, der Switch und der Slider von Mantine erzeugten in ihrem dokumentierten Verwendungsbeispiel jeweils mindestens einen axe-Verstoß, meist durch fehlende zugängliche Namen am zugrunde liegenden Input. Chakra UI v3 — das Ende 2024 auf eine Zag-basierte Zustandsmaschinarchitektur umgestellt wurde — hat viele v2-Probleme behoben, liefert aber nach wie vor einen Tooltip, der nur durch Hover ausgelöst wird. Das ist ein Verstoß gegen WCAG 1.4.13 (Inhalt bei Hover oder Fokus) in axe und ein Tastaturfallen-Risiko im virtuellen Modus von Screenreadern.
3. Matrix der Musterabdeckung
Die folgende Elf-Muster-Tabelle ist die zentrale Referenz. Eine grüne Zelle bedeutet, dass die Bibliothek das Primitiv nativ liefert und axe im Standard-Zustand besteht. Eine gelbe Zelle bedeutet, dass die Bibliothek das Primitiv liefert, aber mindestens ein axe-Verstoß, eine Lücke im Tastaturverhalten oder eine Screenreader-Lücke im dokumentierten Verwendungsbeispiel aufgetreten ist. Ein graues „N/A“ bedeutet, dass die Bibliothek dieses Primitiv nicht liefert — bei shadcn/ui sind das drei Muster, für die Radix direkt importiert oder ein Drittanbieter eingesetzt werden müsste.
| Muster | Radix | React Aria | Ark UI | shadcn | Headless | Mantine | Chakra v3 |
|---|---|---|---|---|---|---|---|
| Dialog | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden |
| Alert-Dialog | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Teilweise | Bestanden |
| Combobox | Bestanden | Bestanden | Bestanden | N/A | Bestanden | Teilweise | Bestanden |
| Listbox | Bestanden | Bestanden | Bestanden | N/A | Bestanden | Bestanden | Bestanden |
| Menü | Bestanden | Bestanden | Bestanden | Bestanden | Teilweise | Bestanden | Bestanden |
| Menüleiste | Bestanden | Bestanden | Bestanden | N/A | N/A | Bestanden | Bestanden |
| Tabs | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden |
| Akkordeon | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden |
| Tooltip | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Teilweise |
| Switch | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Teilweise | Bestanden |
| Slider | Bestanden | Bestanden | Bestanden | Bestanden | Bestanden | Teilweise | Bestanden |
Eine graue N/A-Zelle ist kein Versagen — sie ist eine Beschaffungsfrage. Das shadcn/ui-Modell sieht vor, den benötigten Quellcode aus einem kuratierten Set zu kopieren und dann auszuliefern; für die drei N/A-Muster wird entweder ein Radix-Primitiv direkt importiert oder aus einem Schwester-Registry bezogen. Das Risiko bei shadcn/ui liegt nicht bei den gelieferten Komponenten — diese erben die Konformität von Radix — sondern bei den nicht gelieferten Komponenten, bei denen Teams um 1 Uhr nachts eine Combobox von Grund auf bauen, um eine Deadline einzuhalten.
4. Tastaturverhalten mit Schwächen
Das am häufigsten auftretende Versagen quer durch alle Bibliotheken war kein fehlendes ARIA-Attribut — es war ein Tastaturverhalten, das dem APG beinahe entsprach und dann an einer Taste abwich. Die Combobox von Mantine reagiert nicht auf Pos1 und Ende gemäß APG-Spezifikation. Der Tooltip von Chakra v3 lässt sich nicht mit Escape schließen, wenn er durch Hover geöffnet wurde. Das Menü-Primitiv von Headless UI bricht beim ersten Pfeil-nach-unten zusammen, anstatt den Fokus auf das erste Element zu setzen, weil die Implementierung den Trigger als aktiven Nachfolger beim Öffnen behandelt.
Das sind keine exotischen Randfälle. Es sind die Muster, nach denen Screenreader-Nutzer in der ersten Minute greifen. Der folgende Vergleich stellt dieselbe Combobox-API auf zwei Arten gegenüber — einmal mit Mantines Standard, einmal mit React Aria Components —, um zu zeigen, wie das Tastaturverhalten aussieht, wenn es als Spezifikation und nicht als Polieraufgabe behandelt wird.
<Combobox
store={combobox}
onOptionSubmit={(v) => setValue(v)}
>
<Combobox.Target>
<InputBase
// kein aria-controls-Wiring am Input
// Pos1/Ende bewegen den Fokus nicht in die Listbox
// Pfeil-nach-unten öffnet, setzt aber Fokus nicht auf Element 1
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
/>
</Combobox.Target>
<Combobox.Dropdown>
{/* Listbox-Elemente werden hier gerendert */}
</Combobox.Dropdown>
</Combobox><ComboBox aria-label="Kunden filtern">
<Label>Kunde</Label>
<Input />
<Popover>
<ListBox>
<ListBoxItem>Alpha</ListBoxItem>
<ListBoxItem>Bravo</ListBoxItem>
<ListBoxItem>Charlie</ListBoxItem>
</ListBox>
</Popover>
</ComboBox>
// aria-controls, aria-activedescendant,
// aria-expanded, role=combobox, Pos1/Ende,
// Bild-auf/Bild-ab, Escape: alles standardmäßig verdrahtet.Bibliotheken, die ihr Tastaturverhalten von einer veröffentlichten Spezifikation ableiten — React Aria vom WAI-ARIA APG, Ark UI von den Zag.js-Zustandsmaschinen —, liefern dieses Verhalten als das einzige, das die Komponente unterstützt. Bibliotheken, die das Tastaturverhalten als Featureliste behandeln, liefern davon ungefähr 80 % und lassen die letzten 20 % als „zukünftige Arbeit“ stehen. Diese letzten 20 % sind genau die Tasten, auf die Nutzer assistiver Technologien am häufigsten drücken.
5. Bundle-Größe als Preis der Barrierefreiheit
Das häufigste Argument gegen die strengeren Bibliotheken ist die Bundle-Größe. Das Audit hat dies nicht bestätigt. Radix-UI-Primitive sind per Primitiv tree-shakeable und liegen jeweils im Bereich von ca. 7–15 KB (gzip); React Aria Components ist schwerer — ca. 95 KB (gzip) für das vollständige Bundle — aber ebenfalls tree-shakeable. Headless UI ist mit ca. 25 KB (gzip) für das gesamte Paket das Leichtgewicht. Mantine und Chakra v3 sind beide Batteries-included-Lösungen und bündeln das Styling-System im selben Bundle, was sie im Standard-Zustand in den Bereich von ca. 180–220 KB (gzip) bringt.
Der Trade-off ist real, aber kleiner als der öffentliche Diskurs vermuten lässt. Eine Combobox, die Pos1 und Ende nicht unterstützt, kostet in etwa dieselbe Byte-Anzahl wie eine, die es tut. Die Wahl ist nicht „Barrierefreiheit versus Performance“ — sie ist „spezifikationsgeleitetes Verhalten versus handgefertigtes Verhalten“, und die handgefertigte Version ist häufiger die größere, weil sie ihre eigene Ad-hoc-Zustandsmaschine mitbringt.
6. Leitfaden zur Bibliothekswahl
Bei Enterprise-Anwendungen mit beschaffungsgetriebener Barrierefreiheitsanforderung: React Aria Components wählen.
Es ist die einzige geprüfte Bibliothek, deren APIs explizit vom WAI-ARIA Authoring Practices Guide abgeleitet sind. Das Bundle ist schwerer als bei Radix, aber die Audit-Bestehensgeschichte gegenüber einem VPAT-Gutachter ist am saubersten, da jedes Primitiv einen veröffentlichten Konformitätsanspruch hat.
Wenn das Team sein Design-System selbst verantwortet: Radix UI wählen (und optional shadcn/ui darüber).
Radix liefert ungestylte, spezifikationskonforme Primitive. shadcn/ui macht es einfach, sie einzukopieren und zu themen. Auf die drei Muster, die shadcn nicht liefert — Combobox, Listbox, Menüleiste —, sollte Radix direkt importiert werden, anstatt sie selbst zu implementieren.
Bei Tailwind-first-Teams mit schmalem Bedarf: Headless UI wählen — aber das Menü-Primitiv im eigenen Code auditieren.
Headless UI ist das kleinste Bundle im Feld und liefert eine kleine, gut getestete Fläche. Die eine Menü-Primitiv-Lücke ist oben dokumentiert; sie lässt sich durch explizites aria-activedescendant-Wiring am Listbox-artigen Menü beheben oder durch einen projektlokalen Wrapper, der dies übernimmt.
Wenn Batteries-included wichtiger ist als Spezifikationskonformität: Mantine oder Chakra v3 wählen — aber Überschreibungen einplanen.
Beide Bibliotheken ermöglichen schnelles Ausliefern und sehen gut aus. Beide erfordern aber auch komponentenspezifische Überschreibungen, um den Audit bei Combobox, Switch, Slider (Mantine) oder Tooltip (Chakra v3) zu bestehen. Diese Überschreibungsarbeit gehört in den Sprint, in dem die Bibliothek eingeführt wird — nicht in den Sprint, der den Audit nicht besteht.
axe gegen die eigene Demo der Bibliothek ausführen, bevor sie eingeführt wird.
Anbieter pflegen Demo-Seiten. axe DevTools darauf richten. Falls die Demo des Anbieters bei den Primitiven, die eingesetzt werden sollen, Verstöße auslöst, werden diese Verstöße ins Produkt übernommen. Dieser einzelne Fünf-Minuten-Check trennt die Bibliotheken, die eingesetzt werden, von denen, die es nicht werden.
Fazit: Die Spezifikation ist der Vertrag
Die Bibliotheken, die einen axe-Audit sauber bestehen, sind jene, deren Autoren den WAI-ARIA Authoring Practices Guide als Vertrag und nicht als Referenz behandelt haben. Radix UI, React Aria Components und Ark UI leiten ihr Tastaturverhalten und ihr ARIA-Wiring jeweils von einer veröffentlichten Spezifikation ab — dem APG für Radix und React Aria, den Zag.js-Zustandsmaschinen für Ark UI — und liefern die Spezifikation, keine Teilmenge davon.
Die Bibliotheken, die scheitern, tun dies nicht, weil ihre Autoren Barrierefreiheit egal wäre. Sie scheitern, weil das Tastaturverhalten als Featureliste behandelt wurde, und Featurelisten enden bei 80 % statt 100 %. Die letzten 20 % — Pos1 und Ende in einer Combobox, Escape zum Schließen eines per Hover geöffneten Tooltips, Fokusmanagement beim ersten Pfeil-nach-unten in einem Menü — sind der Teil, den Nutzer bemerken.
Die shadcn/ui-Geschichte steht merkwürdig zwischen beiden Kategorien. Die gelieferten Komponenten erben Radix’ Spezifikationsableitung und bestehen. Die nicht gelieferten Komponenten sind die Lücken, in denen Teams eine In-House-Combobox von Grund auf bauen — und diese In-House-Combobox ist der Ort, an dem der nächste axe-Verstoß in die Codebasis eintritt. Die Lösung ist nicht, eine andere Bibliothek zu wählen — sie ist, Radix für diese drei Muster direkt zu importieren und sie mit derselben Ernsthaftigkeit zu behandeln wie den Rest des Design-Systems.
Engineering-Teams, die eine Bibliothek einführen, sollten die Wahl mit dem restlichen Entwickler-Toolkit auf unserer Entwickler-Landingpage verknüpfen, einen kostenlosen WCAG-2.2-Scan der Demo der Bibliothek durchführen, bevor sie in die Produktion geht, und das Ergebnis an der vollständigen WCAG-2.2-Erfolgskriterien-Referenz messen.
„Wer die Bibliothek wählt, deren Autoren die Spezifikation als Vertrag behandelt haben, macht aus dem Audit eine Formsache. Wer die Bibliothek wählt, deren Autoren die Spezifikation als Referenz behandelt haben, macht aus dem Audit einen Rückstand.“