← Zurück zu Design Systems and Frontend Team

Skill · Version 1.0.0

Tastatur und Fokus

Gestaltet vorhersehbare Tastaturnavigation und sichtbaren Fokus über Widgets, Fenster, Löschungen und Seitenwechsel hinweg.

keyboard-focus-engineering

Teammitglieder mit diesem Skill

Entdecke, wie der Skill hilft

Wann ist der Skill hilfreich?

Nutze dies bei Tastaturfallen oder verlorenem Fokus ohne Maus.

Wobei hilft er dir?

  • Erhält logische Tab-Reihenfolge ohne positive Tabindex-Umwege.
  • Wählt das passende Fokusmodell für zusammengesetzte Widgets.
  • Setzt sinnvollen Fokus nach Schließen, Löschen oder Navigation zurück.

Das könntest du fragen

Korrigiere den Fokus nach einem Tabellenaktionsdialog, auch wenn dessen Zeile inzwischen gelöscht wurde. Lösche die Ausgangszeile bei offenem Dialog. Beim Schließen erhält ein sinnvolles verbleibendes Tabellenbedienelement den Fokus statt der entfernten Schaltfläche.

Ausführliche Dokumentation

Hier findest du die ursprüngliche Anleitung, Beispiele und Prüfschritte des Skills in ihrer Originalsprache.

Details…Weniger anzeigen

Keyboard & Focus Engineering

Every interactive user journey must work end-to-end with a keyboard alone, with a clearly visible focus indicator, predictable tab order and deliberate focus restoration when overlays open, close or remove elements (WCAG 2.1.1, 2.1.2, 2.4.1, 2.4.3, 2.4.7, 2.4.11).

1. Tab Order & Tabindex Discipline

  • DOM order drives focus order: arrange elements in the DOM so Tab and Shift+Tab follow the visual reading and task sequence (WCAG 2.4.3). Avoid CSS reordering (flex-direction: row-reverse, arbitrary order or absolute positioning) that disconnects visual order from DOM tab order.
  • Tabindex rules:
    • Prefer native focusable elements (<button>, <a href>, <input>, <select>, <textarea>, <summary>).
    • Use tabindex="0" only to add a custom widget's active entry point to the tab sequence or make a scrollable region keyboard-scrollable.
    • Use tabindex="-1" for elements targeted by programmatic .focus() (headings, dialog containers or inactive items inside a roving-tabindex composite widget).
    • Never use positive tabindex (tabindex="1", 2, etc.) — it hijacks page-wide tab order.
  • Bypass blocks (WCAG 2.4.1): provide a working "Skip to main content" link as the first focusable item on shells with repeated navigation.

2. Composite Widgets: Roving Tabindex vs. aria-activedescendant

Complex widgets (tablists, menus, toolbars, radio groups, tree views, grids) must be a single tab stop:

  • Tab / Shift+Tab moves into and out of the composite widget as a whole; Arrow keys, Home and End move between items inside it.
  • Roving tabindex pattern: give the active item tabindex="0" and all sibling items tabindex="-1". On arrow key press, move tabindex="0" to the target item, set the previous item to -1, and call .focus().
  • aria-activedescendant pattern (for comboboxes where focus stays on the text <input>): keep DOM focus on the <input>, update aria-activedescendant="option-id" on ArrowDown/ArrowUp, and scroll the active option into view (scrollIntoView({ block: 'nearest' })).

3. Focus Lifecycle in Overlays, Deletions & Route Changes

Plan where focus goes before, during and after every structural UI transition:

  • Opening a modal dialog or drawer:
    1. Save document.activeElement before opening.
    2. Move initial focus inside the dialog (first primary field, primary action, or dialog heading/container with tabindex="-1").
    3. Contain Tab/Shift+Tab inside the modal (<dialog>.showModal(), inert on background siblings, or focus trap) and close on Escape.
  • Closing a dialog or popover: restore focus to the opener, or to the nearest logical parent/trigger if the opener was unmounted.
  • Deleting an item from a list or table: never let focus drop to <body>. Move focus to the next sibling item, the previous item if the last one was deleted, or the list heading / "Add" button when empty.
  • Hidden and inert content: ensure elements inside closed drawers, inactive tabs or collapsed panels are unfocusable (hidden, inert or display: none). Never place a focusable element inside an aria-hidden="true" container.

4. Visible Focus Indicators (WCAG 2.4.7 & 2.4.11)

  • Use :focus-visible to render a high-contrast focus ring (at least 2px solid outline with outline-offset and >= 3:1 contrast).
  • Never use outline: none without a visible :focus-visible replacement that survives forced-colors: active mode.
  • Prevent sticky headers or footers from obscuring focused elements (scroll-margin-top / scroll-margin-bottom).

Enthaltene Dateien 1

  • SKILL.md