accessibility

Tabindex-Best-Practices

Markiert positive tabindex-Werte und übermäßigen Einsatz von tabindex="-1". Positive Werte brechen die DOM-Reihenfolge; nur 0 und -1 gehören in Produktions-Markup.

Was diese Prüfung macht

Scannt alle Elemente mit einem tabindex-Attribut und meldet zwei Probleme:

  1. Positive Werte (tabindex="1", "2" etc.) — sie überschreiben die natürliche DOM-Tab-Reihenfolge und verursachen fast immer Fokus-Bugs.
  2. Übermäßiger Einsatz von tabindex="-1" auf Elementen, die per Tastatur erreichbar sein sollten — ein häufiger Fehler bei Custom-Buttons und -Links.

Die Prüfung weist auch darauf hin, wenn tabindex auf nativ fokussierbaren Elementen (<a href>, <button>, <input>) gesetzt ist, wo es meist redundant ist.

Warum es zählt

Ein positiver tabindex schafft ein paralleles Tastatur-Universum. Der Browser tabt zuerst durch alle positiven Werte — in numerischer Reihenfolge — und fällt dann auf die DOM-Reihenfolge für alles andere zurück. Setze tabindex="1" auf ein Element und du hast es vor jeden Link, Button und jedes Formularfeld der Seite gehoben. Setze es auf zehn Elemente und du hast die Tab-Reihenfolge manuell neu nummeriert — was bedeutet, dass jede künftige Änderung (ein neuer Menüpunkt, ein vertauschtes Formularfeld) die Sequenz still bricht.

WCAG 2.4.3 (Focus Order) verlangt, dass sich der Fokus in einer Reihenfolge bewegt, die Sinn und Bedienbarkeit erhält. Die visuelle Reihenfolge sollte der Tab-Reihenfolge entsprechen. Positiver tabindex verstößt fast immer dagegen — Tastatur- und Screenreader-Nutzer:innen landen an überraschenden Stellen, verlieren den Kontext und brechen ab.

tabindex="-1" hat bei Missbrauch das umgekehrte Problem: Es entfernt ein Element komplett aus der Tab-Sequenz. Setz es auf einen Button und Tastaturnutzer:innen können ihn nicht mehr erreichen.

So behebst du es

Faustregel: In normalem Anwendungscode sind die einzig akzeptablen Werte tabindex="0" und tabindex="-1", und du brauchst sie nur auf nicht-nativen Elementen.

Wann tabindex="0" richtig ist

Ein Custom-Interactive-Widget, das der Browser nicht standardmäßig fokussiert:

<!-- Custom-Tab in einer Tablist -->
<div role="tab" tabindex="0" aria-selected="true">Übersicht</div>

<!-- Card, die per Klick ein Modal öffnet -->
<div role="button" tabindex="0" onclick="openModal()">
  Details anzeigen
</div>

Bevorzuge wann immer möglich einen echten <button> — er liefert Fokus, Enter/Space-Aktivierung und Screenreader-Semantik gratis. Greif nur zu tabindex="0", wenn das native Element nicht reicht.

Wann tabindex="-1" richtig ist

Ein programmatisches Fokus-Ziel — ein Element, das du per JavaScript fokussierst, das aber nicht in der Tab-Sequenz auftauchen soll:

<!-- Error-Summary, fokussiert beim Submit -->
<div id="errors" tabindex="-1" role="alert">
  3 Felder benötigen Aufmerksamkeit
</div>

<!-- Modal-Container, fokussiert beim Öffnen -->
<div id="modal" tabindex="-1" role="dialog" aria-modal="true">
  ...
</div>

<!-- Skip-Link-Ziel (Hauptinhalt) -->
<main id="main" tabindex="-1">...</main>

Dann im JS:

document.getElementById("errors").focus();

Das -1 lässt .focus() funktionieren, ohne das Element in die Tab-Reihenfolge einzufügen.

Wann positiver tabindex richtig ist

Fast nie. Der einzige verteidigbare Fall ist die Integration in ein Legacy-Formular, bei dem du das DOM nicht umsortieren kannst und die visuelle Reihenfolge eine Neuordnung verlangt — und selbst dann ist das Reparieren des DOM die richtige Antwort.

In CI linten

Fang das vor dem Review ab:

bun add -D eslint-plugin-jsx-a11y
// eslint.config.js
import jsxA11y from "eslint-plugin-jsx-a11y";

export default [{
  plugins: { "jsx-a11y": jsxA11y },
  rules: {
    "jsx-a11y/tabindex-no-positive": "error",
    "jsx-a11y/no-noninteractive-tabindex": "warn",
  },
}];

Für reine HTML-/Template-Repos fängt axe-core dasselbe Problem zur Audit-Zeit ab — siehe Lighthouse-Accessibility-Fehler.

Eine Seite reparieren, die bereits positiven tabindex hat

  1. Entferne jedes tabindex="1+"-Attribut.
  2. Tabbe per Tastatur durch die Seite. Notiere überraschende Sprünge.
  3. Sortiere das DOM um, sodass die natürliche Sequenz der visuellen entspricht. Nutze CSS (order, Grid-Placement) nur für visuelle Umpositionierung, die die Lesereihenfolge nicht beeinflusst.
  4. Audit erneut laufen lassen.

Häufig gestellte Fragen

Kann ich tabindex="0" nutzen, um einen <div> klickbar zu machen?

Du kannst — aber role="button" plus Enter/Space-Handler hinzuzufügen ist schon die halbe Arbeit, und ein echter <button> ist ein Element mit allem verdrahtet. Das Muster tabindex="0" + role="button" ist Fällen vorbehalten, in denen du ein Nicht-Button-Element brauchst (z. B. ein treeitem, ein Tab), das die Spec nicht als nativ fokussierbar kennt.

Versteckt tabindex="-1" das Element vor Screenreadern?

Nein. tabindex="-1" entfernt das Element nur aus der sequenziellen Tastaturnavigation. Screenreader können es weiterhin über ihre eigene Navigation (Überschriften, Landmarks, virtueller Cursor) erreichen. Um vor assistiver Technologie zu verbergen, nutze aria-hidden="true" — aber niemals auf einem interaktiven Element.

Was ist mit Roving Tabindex in einem Menü oder Grid?

Das ist das richtige Muster für Composite-Widgets (Menüs, Tablisten, Grids). Genau ein Item hat tabindex="0", der Rest tabindex="-1", und Pfeiltasten bewegen den Fokus, indem sie die Werte tauschen. Die Prüfung berücksichtigt das: Eine einzelne 0 plus viele -1s innerhalb derselben role="menu" / role="tablist" / role="grid" wird nicht gemeldet.

Quellen

Zuletzt aktualisiert 2026-05-11