Konzepte

Fokusfalle

Das Muster, das den Tastaturfokus in einem modalen Dialog hält, solange dieser geöffnet ist — verhindert, dass Tab in das dahinterliegende Dokument springt, und gibt den Fokus beim Schließen an das auslösende Element zurück.

Eine Fokusfalle ist eine bewusste Einschränkung der Tastaturnavigation: Solange ein modaler Dialog geöffnet ist, wechselt Tab nur zwischen den fokussierbaren Elementen innerhalb des Dialogs. Shift+Tab geht in die entgegengesetzte Richtung. Der Nutzende kann nicht per Tab in die (visuell verdeckte) Seite hinter dem Dialog gelangen, bis er ihn explizit schließt.

Das Einschließen des Fokus ist für zugängliche modale Dialoge erforderlich. Ohne diese Maßnahme geraten Tastatur- und Screenreader-Nutzende auf unsichtbare Seiteninhalte, die sie weder sehen noch verlassen können.

Warum diese Maßnahme notwendig ist

Ein modaler Dialog wird visuell als Ebene über der Seite dargestellt. Die klare Absicht ist, dass der Nutzende mit dem Dialog interagiert, bis er fertig ist, und dann zur Seite zurückkehrt. Für Mausnutzer ist das intuitiv: Ein Klick außerhalb des Dialogs hat keine Wirkung (oder schließt ihn); ein Klick innerhalb erreicht die Steuerelemente des Dialogs.

Ohne Fokusfalle erhalten Tastaturnutzer ein inkonsistentes Erlebnis:

  1. Der Dialog öffnet sich. Der Fokus wechselt zum (oder sollte wechseln zum) ersten fokussierbaren Element darin.
  2. Der Nutzende drückt Tab. Der Fokus geht zum nächsten fokussierbaren Element innerhalb des Dialogs.
  3. Der Nutzende drückt weiter Tab. Der Fokus erreicht schließlich das letzte fokussierbare Element innerhalb des Dialogs.
  4. Noch ein Tab. Ohne Fokusfalle springt der Fokus zum nächsten fokussierbaren Element im Dokument — irgendwo hinter dem Dialog, für den Nutzenden unsichtbar.

Das einzige Signal dafür ist, dass der Fokusindikator des Dialogs verschwindet. Der Nutzende weiß nicht, wo sich sein Fokus befindet.

Das vollständige Modal-Muster

Ein vollständig zugänglicher modaler Dialog umfasst:

  1. Der Fokus wechselt in den Dialog, wenn er öffnet — typischerweise zum ersten fokussierbaren Element oder zur Überschrift des Dialogs (wenn die Überschrift tabindex="-1" für programmatischen Fokus hat).
  2. Der Fokus ist eingeschlossen im Dialog: Tab vom letzten Element springt zum ersten; Shift+Tab vom ersten springt zum letzten.
  3. Escape schließt den Dialog und gibt den Fokus an das auslösende Element zurück, das ihn geöffnet hat (nicht an den Dokument-Body).
  4. Ein Klick außerhalb des Dialogs schließt ihn — optionales Verhalten; nicht alle Dialoge tun dies, aber wenn der Dialog dies unterstützt, muss der Fokus während des Öffnens trotzdem eingeschlossen bleiben.
  5. role="dialog" plus aria-modal="true" am Dialog-Element, mit aria-labelledby, das auf die Überschrift des Dialogs verweist.

Implementierungen

Die meistgenannte Bibliothek ist focus-trap (npm: focus-trap, focus-trap-react, focus-trap-vue) — klein, ohne Abhängigkeiten und deckt alle Grenzfälle ab (Überspringen unsichtbarer Elemente, Integration mit inert, Fokuswiederherststellung beim Schließen).

Das moderne Browser-Primitiv ist <dialog> mit dialog.showModal(), das den Fokus automatisch einschließt und Escape verarbeitet. Die Browser-Unterstützung ist mittlerweile stark genug, um dies als Ausgangspunkt zu nutzen.

Anti-Pattern: Die „Falle, die nicht loslässt“

Eine Fokusfalle muss freigeben, wenn der Dialog schließt. Der häufigste Implementierungsfehler ist das Vergessen, den Fokus zum ursprünglichen auslösenden Element zurückzugeben — der Fokus landet dann auf dem Dokument-Body, den Screenreader als nichts ankündigen. Der Nutzende wird in die Stille entlassen und muss vom Seitenanfang an neu navigieren.