Pflicht-ARIA-Attribut fehlt (aria-required-attr)

Die Regel aria-required-attr meldet ein Element, dessen ARIA-Rolle einen Zustand oder eine Eigenschaft braucht, die fehlt – ein role="switch" ohne aria-checked, ein role="slider" ohne aria-valuenow. Die Rolle sagt assistiven Technologien, was das Bedienelement ist; ohne den Pflichtzustand weiß niemand, ob es an, aus oder auf 40 % steht. Die Lösung: das Attribut ergänzen und mit dem Bedienelement mitführen.

Was die Regel bedeutet

WAI-ARIA 1.2 legt für jede Rolle fest, welche Zustände und Eigenschaften ein Autor angeben muss [3]. axe-core prüft diese:

  • checkbox, radio, switch, menuitemcheckbox, menuitemradio – aria-checked;
  • slider, scrollbar, meter und ein fokussierbarer separator – aria-valuenow;
  • combobox – aria-expanded und aria-controls;
  • heading – aria-level.

Die Regel betrachtet nur Rollen, die in einem role-Attribut stehen. Native HTML-Elemente bringen diese Zustände schon mit: Ein <input type="checkbox"> hat einen Auswahlzustand, ein <h2> eine Ebene, ein <input type="range"> einen Wert. Drei Ausnahmen sind eingebaut. Eine geschlossene Combobox (aria-expanded="false") braucht noch kein aria-controls. Ein Schieberegler mit aria-valuetext wird auch ohne aria-valuenow akzeptiert. Ein separator, der keinen Fokus bekommt, ist eine einfache Trennlinie und braucht keinen Wert.

Ob der Wert stimmt oder sich bei der Bedienung ändert, prüft die Regel nicht.

Wen es betrifft

Wer einen Screenreader nutzt, hört „Schalter“ oder „Schieberegler“ und dann nichts über den Zustand – ob Benachrichtigungen an sind oder wie laut die Lautstärke ist, bleibt offen. Wer per Sprachsteuerung oder Schaltersteuerung arbeitet, kann das Element vielleicht bedienen, bekommt aber keine Rückmeldung, dass sich etwas geändert hat. Ein fehlendes aria-level nimmt außerdem eine Überschrift aus der Gliederung, mit der viele Screenreader-Nutzende sich bewegen.

Warum die Prüfung anschlägt

  • Eigene Umschalter im Designsystem: ein <button role="switch"> als Pille gestaltet, der Zustand steckt nur in einer CSS-Klasse.
  • Selbst gebaute Schieberegler aus einem Karussell- oder Preisfilter-Plugin, die aria-valuemin und aria-valuemax setzen, aber nie den aktuellen Wert.
  • Comboboxen aus Autocomplete-Bibliotheken, die role="combobox" setzen, aber aria-expanded weglassen.
  • role="heading" an einem <div> aus dem Seitenbaukasten, ohne aria-level.
  • Serverseitig erzeugtes Markup, das sich darauf verlässt, dass ein Skript den Zustand später ergänzt – das Skript schlägt fehl oder ist noch nicht gelaufen.
  • Eine Rolle, die einen anderen Befund beheben sollte, ohne nachzulesen, welche Attribute dazugehören.

So beheben Sie es

  1. Schlagen Sie nach, welche Zustände die Rolle verlangt – in WAI-ARIA 1.2 [3] oder im passenden Muster des ARIA Authoring Practices Guide [5].
  2. Ergänzen Sie sie in der Komponente, mit einem ehrlichen Startwert.
  3. Aktualisieren Sie den Wert bei jeder Änderung.
  4. Noch besser: das native Element verwenden. <input type="checkbox" role="switch"> oder <input type="range"> bringen ihren Zustand mit, ohne dass Sie ARIA pflegen müssen.
<!-- Vorher: ein Schalter ohne Zustand, ein Schieberegler ohne Wert -->
<div class="einstellungen">
  <span id="mail-label">E-Mail-Benachrichtigungen</span>
  <button class="umschalter" role="switch" aria-labelledby="mail-label"></button>
  <span id="lautstaerke-label">Lautstärke</span>
  <div class="regler" role="slider" tabindex="0" aria-labelledby="lautstaerke-label"
       aria-valuemin="0" aria-valuemax="100"></div>
</div>
<!-- Nachher: jede Rolle hat den Zustand, den sie verlangt -->
<div class="einstellungen">
  <span id="mail-label">E-Mail-Benachrichtigungen</span>
  <button class="umschalter" role="switch" aria-checked="false" aria-labelledby="mail-label"></button>
  <span id="lautstaerke-label">Lautstärke</span>
  <div class="regler" role="slider" tabindex="0" aria-labelledby="lautstaerke-label"
       aria-valuemin="0" aria-valuemax="100" aria-valuenow="40"></div>
</div>

Der Zustand muss dem Bedienelement folgen. Für den Schalter:

// Den Zustand im selben Handler umschalten, der die Einstellung umschaltet
umschalter.addEventListener('click', () => {
  const an = umschalter.getAttribute('aria-checked') === 'true'
  umschalter.setAttribute('aria-checked', String(!an))
})

So prüfen Sie es von Hand

  1. Wählen Sie das Element in den Entwicklertools Ihres Browsers aus und öffnen Sie den Bereich „Barrierefreiheit“. Dort stehen Rolle und die Zustände, die der Browser weitergibt.
  2. Bedienen Sie das Element mit der Tastatur – Leertaste beim Schalter, Pfeiltasten beim Schieberegler – und prüfen Sie, ob sich der Zustand dort ändert.
  3. Prüfen Sie mit einem Screenreader wie NVDA (kostenlos) oder VoiceOver, ob der Zustand beim Erreichen des Elements und bei jeder Änderung angesagt wird.
  4. Was die Regel nicht sieht: einen Zustand, der da ist, aber nicht stimmt, oder einen, der sich nie aktualisiert.

Zugehöriges WCAG-Kriterium

4.1.2 Name, Rolle, Wert, Stufe A: Der Zustand eines Bedienelements muss für assistive Technologien verfügbar sein. Bei einer Überschrift ohne Ebene ist zusätzlich 1.3.1 Info und Beziehungen betroffen.

So meldet Reviseberg diese Regel

Reviseberg führt aria-required-attr auf jeder gecrawlten Seite aus. In der Befundliste steht die Regel mit Schweregrad, WCAG 4.1.2 und Stufe A, der Zahl der Elemente und Seiten und den Punkten, die ein Fix zurückbringt. Im Detail sehen Sie Selektor, HTML-Ausschnitt und alle betroffenen Seiten. Ein Schalter oder Schieberegler stammt meist aus einer Komponente; derselbe Befund erscheint dann auf vielen Seiten, und ein Fix behebt sie gemeinsam. Befunde können Sie mit Begründung als „ignorieren“, „nicht behebbar“ oder „Fehlalarm“ markieren; jede Entscheidung wird protokolliert. Ein sauberer Lauf klärt 4.1.2 nicht – ob der Zustand mit dem Bedienelement Schritt hält, zeigt erst ein Mensch, der es bedient.

Verwandte Regeln

  • undefined – das Attribut ist da, aber sein Wert ist nicht erlaubt.
  • undefined – ein Attribut, das die Rolle nicht unterstützt.
  • undefined – eine Rolle, die bestimmte Kind-Rollen braucht, etwa eine Listbox ohne Optionen.

Komponenten auf fehlende ARIA-Zustände prüfen – kostenloser Scan

Häufige Fragen

Braucht <input type="checkbox"> ein aria-checked?

Nein. Die native Checkbox gibt ihren Zustand selbst weiter. Ein zusätzliches aria-checked wäre nur ein zweiter Wert, der vom echten abweichen kann.

Warum besteht eine Combobox ohne aria-controls?

Solange sie geschlossen ist (aria-expanded="false"), gibt es das Popup vielleicht noch nicht; axe verlangt den Verweis dann nicht. Sobald sie sich öffnet, muss aria-controls auf die Liste zeigen.

Genügt aria-valuetext an einem Schieberegler?

axe akzeptiert es. Screenreader lesen aria-valuetext statt der Zahl vor, was bei Werten wie „250 €“ oder „Mittel“ hilft. Wo es eine Zahl gibt, setzen Sie aria-valuenow trotzdem mit.

Darf ich den Zustand erst setzen, wenn das Skript geladen ist?

Die Regel sieht die Seite nach dem Laden; einen Zustand, den ein gelaufenes Skript gesetzt hat, zählt sie also mit. Einen Zustand, der erst beim ersten Klick entsteht, nicht.

Quellen

  1. W3C, Understanding SC 4.1.2 Name, Role, Value – https://www.w3.org/WAI/WCAG22/Understanding/name-role-value
  2. Deque University, axe-core 4.13 Regel aria-required-attr – https://dequeuniversity.com/rules/axe/4.13/aria-required-attr
  3. W3C, Accessible Rich Internet Applications (WAI-ARIA) 1.2 – https://www.w3.org/TR/wai-aria-1.2/
  4. W3C, ACT-Regel: Element with role attribute has required states and properties – https://www.w3.org/WAI/standards-guidelines/act/rules/4e8ab6/
  5. W3C, ARIA Authoring Practices Guide: Switch Pattern – https://www.w3.org/WAI/ARIA/apg/patterns/switch/
  6. W3C, ARIA Authoring Practices Guide: Slider Pattern – https://www.w3.org/WAI/ARIA/apg/patterns/slider/

Sehen Sie, was ein Scan auf Ihrer Website findet

Eine Seite in rund 30 Sekunden, ohne E-Mail. Der vollständige Bericht umfasst bis zu 100 Seiten und einen Tastatur-Durchlauf.