Ungültiger ARIA-Wert (aria-valid-attr-value)

Die Regel aria-valid-attr-value meldet ARIA-Attribute, deren Wert die WAI-ARIA-Spezifikation nicht vorsieht – aria-expanded="yes", aria-valuenow="50%" oder ein aria-controls, das auf eine ID zeigt, die es nicht gibt. Einen Zustand, den der Browser nicht versteht, kann er nicht weitergeben. Die Lösung: genau den Wert verwenden, den das Attribut definiert, und Verweise auf vorhandene IDs richten.

Was die Regel bedeutet

Jedes ARIA-Attribut hat in WAI-ARIA 1.2 einen Werttyp [3]. Manche nehmen true oder false (aria-disabled), manche true, false oder mixed (aria-checked), manche eine feste Liste von Werten (aria-haspopup: menu, listbox, tree, grid, dialog), manche eine Zahl (aria-valuenow, aria-level) und manche eine oder mehrere IDs anderer Elemente (aria-controls, aria-labelledby). Alles außerhalb dieser Menge ist ungültig; der Browser ignoriert es oder fällt auf einen Standardwert zurück.

axe prüft jedes aria-*-Attribut an jedem Element. Als Fehler meldet es einen Wert außerhalb der Menge – auch einen Verweis per aria-controls oder aria-owns auf eine ID, die auf der Seite fehlt, solange das Element aufgeklappt ist. In einigen Fällen fragt es stattdessen einen Menschen:

  • aria-labelledby oder aria-describedby zeigen nur auf IDs, die nicht auf der Seite sind – das Ziel kann später eingefügt werden;
  • aria-current hat einen Wert außer page, step, location, date, time, true, false;
  • ein leerer Wert an einem Attribut, das keinen freien Text erwartet;
  • aria-controls an einem Element mit aria-haspopup, dessen Popup erst beim Öffnen entsteht.

Die Regel prüft nicht, ob ein gültiger Wert auch stimmt: aria-expanded="false" an einem sichtbar geöffneten Menü besteht.

Wen es betrifft

Wer einen Screenreader nutzt, hört den Zustand, den das Markup ansagt – „reduziert“, „aktiviert“, „3 von 5“ – und sonst nichts. Ist der Wert ungültig, hört man nichts oder einen falschen Standardwert und muss raten, ob sich ein Bereich geöffnet hat. Auch wer per Sprachsteuerung „Klick Versand“ sagt, erfährt nicht, dass sich etwas geändert hat.

Warum die Prüfung anschlägt

  • Wörter statt Werte: aria-expanded="yes", aria-hidden="hidden", aria-selected="selected", abgeschrieben von Klassennamen.
  • Template-Ausgabe: Ein Framework schreibt aria-expanded="${isOpen}" wörtlich hinein oder aria-checked="null", wenn der Zustand nie gesetzt wurde.
  • Einheiten in Zahlen: aria-valuenow="50%" oder aria-level="h3".
  • Tippfehler in IDs: aria-controls="panel-versnd" gegenüber id="panel-versand".
  • Komponenten ohne ihr Ziel: Der Aufklapp-Button bleibt, das Panel, das er steuert, hat das CMS entfernt.
  • Alte ARIA-Gewohnheiten: aria-haspopup="yes" oder aria-live="on" – beides war nie gültig.

So beheben Sie es

  1. Schlagen Sie die erlaubten Werte des Attributs in WAI-ARIA 1.2 nach [3] – bei den meisten ist die Liste kurz.
  2. Korrigieren Sie den Wert in der Komponente, nicht auf der Seite: Meist erzeugt ein einziges Akkordeon-Template alle Vorkommen.
  3. Lassen Sie das Skript, das den Bereich auf- und zuklappt, auch den Zustand schreiben. Dann bleibt er richtig.
<!-- Vorher: "yes" kennt aria-expanded nicht, und die ID hat einen Tippfehler -->
<div class="akkordeon">
  <h3 class="akkordeon__kopf">
    <button class="akkordeon__schalter" aria-expanded="yes" aria-controls="panel-versnd">
      Versand und Rückgabe
    </button>
  </h3>
  <div class="akkordeon__panel" id="panel-versand">
    <p>Kostenlose Rückgabe innerhalb von 30 Tagen.</p>
  </div>
</div>
<!-- Nachher: ein gültiger Wert und ein Verweis auf eine vorhandene ID -->
<div class="akkordeon">
  <h3 class="akkordeon__kopf">
    <button class="akkordeon__schalter" aria-expanded="true" aria-controls="panel-versand">
      Versand und Rückgabe
    </button>
  </h3>
  <div class="akkordeon__panel" id="panel-versand">
    <p>Kostenlose Rückgabe innerhalb von 30 Tagen.</p>
  </div>
</div>

Ein gültiger Wert ist nur die halbe Arbeit. Der Zustand muss dem Panel folgen:

// Den Zustand dort schreiben, wo das Panel auf- und zugeklappt wird
schalter.addEventListener('click', () => {
  const offen = schalter.getAttribute('aria-expanded') === 'true'
  schalter.setAttribute('aria-expanded', String(!offen)) // immer "true" oder "false"
  panel.hidden = offen
})

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“ (Chrome, Edge, Firefox). Er zeigt Rolle, Namen und die Zustände, die der Browser tatsächlich verstanden hat.
  2. Bedienen Sie das Widget – Akkordeon öffnen, Tab wählen, Schieberegler bewegen – und beobachten Sie, wie sich der Zustand dort ändert.
  3. Prüfen Sie mit einem Screenreader (NVDA ist kostenlos, VoiceOver ist in macOS und iOS enthalten), ob „erweitert“ und „reduziert“ zu dem passen, was Sie sehen.
  4. Was die Regel nicht sieht: einen gültigen, aber falschen Zustand, einen Zustand, der sich nie aktualisiert, und einen Wert am falschen Element.

Zugehöriges WCAG-Kriterium

4.1.2 Name, Rolle, Wert, Stufe A: Zustände und Eigenschaften eigener Bedienelemente müssen für assistive Technologien verfügbar sein. Ein Verweis auf eine fehlende ID kann außerdem eine Beziehung nach 1.3.1 Info und Beziehungen zerreißen.

So meldet Reviseberg diese Regel

Reviseberg führt aria-valid-attr-value 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 mit dem ungültigen Wert und alle betroffenen Seiten. Weil der Wert meist aus einer Komponente stammt, behebt ein Fix oft viele Seiten auf einmal.

Die Fälle, die axe offenlässt – Verweise auf noch fehlende IDs, ungewöhnliche aria-current-Werte, leere Werte –, landen in der Warteschlange „Mögliche Probleme“. Dort entscheidet ein Mensch; sie kosten nichts und zählen nie als bestanden. 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 jeder Zustand stimmt, bleibt eine Frage für einen Menschen.

Verwandte Regeln

  • undefined – ein Pflichtzustand wie aria-checked fehlt ganz.
  • undefined – das Attribut ist gültig, aber für diese Rolle nicht vorgesehen.
  • undefined – ein Button ohne Namen, etwa weil sein aria-labelledby ins Leere zeigt.

Ungültige ARIA-Werte auf Ihrer Website finden – kostenloser Scan

Häufige Fragen

Ist aria-expanded="yes" wirklich ein Fehler? Screenreader kommen vielleicht damit klar.

Der Wert ist nach WAI-ARIA 1.2 ungültig; erlaubt sind nur true, false und undefined. Browser raten nicht, also wird der Button nicht als erweitert angesagt.

Warum ist ein aria-describedby auf eine fehlende ID nur ein mögliches Problem?

Weil das Ziel später eingefügt werden kann, etwa eine Fehlermeldung nach dem Absenden. axe kann das nicht wissen und fragt deshalb einen Menschen, statt die Seite durchfallen zu lassen.

Zählt aria-hidden="False" mit großem F?

Die Werte werden ohne Rücksicht auf Groß- und Kleinschreibung verglichen, also wird es akzeptiert. Schreiben Sie trotzdem klein – so steht es in der Spezifikation.

Prüft die Regel, ob der Zustand stimmt?

Nein. Sie prüft die Form des Werts. aria-expanded="false" an einem offenen Menü besteht; dass es falsch ist, zeigt erst die Bedienung.

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-valid-attr-value – https://dequeuniversity.com/rules/axe/4.13/aria-valid-attr-value
  3. W3C, Accessible Rich Internet Applications (WAI-ARIA) 1.2 – https://www.w3.org/TR/wai-aria-1.2/
  4. W3C, ACT-Regel: ARIA state or property has valid value – https://www.w3.org/WAI/standards-guidelines/act/rules/6a7281/
  5. W3C, ARIA Authoring Practices Guide: Accordion Pattern – https://www.w3.org/WAI/ARIA/apg/patterns/accordion/

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.