JavaScript focus visible

Fokus setzen und die Markierung zeigen

Fehlermeldung, Dialog, Sprungziel: drei Stellen, an denen Skripte fokussieren.

Website prüfen
Beispiel im Prüfbericht Markierter Befund
Markierter Befund · Kritisch · WCAG 4.1.2Erreichbarer Link im verborgenen Bereich

Fokus-Choreografie

JavaScript bestimmt die Landung. CSS zeigt sie.

Fokuspunkt, sichtbarer Rahmen und Scrollposition sind drei getrennte Entscheidungen.

Drei Fokussprünge, drei räumliche AufgabenKonzeptionelle Darstellung, keine Produktoberfläche
1

Fehler erklären

Vom Absenden zur Meldung vor dem Feld.

Fokuspfad zur Fehlermeldung Der Fokus bewegt sich von der Schaltfläche unten zur Fehlermeldung über dem E-Mail-Feld. Der Browser darf die Meldung ins Bild scrollen.
Bitte E-Mail-Adresse prüfenE-Mail-AdresseKonto anlegen
fehler.focus()Scrollen: Browser
2

Dialog betreten

Vom Öffner zum Titel und wieder zurück.

Fokuspfad in den Dialog und zurück Der Fokus bewegt sich vom Öffner in den bereits sichtbaren Dialog. Beim Schließen kehrt er zum Öffner zurück. Die Seite soll dabei nicht scrollen.
Warenkorb
Bestellung prüfenZwei Artikel im WarenkorbSchließen
titel.focus({ preventScroll: true })Scrollen: aus
3

Zum Inhalt springen

Vom Kopf zum weit entfernten Hauptbereich.

Fokuspfad zum Hauptinhalt Ein Sprunglink setzt den Fokus vom Seitenkopf auf den Hauptbereich weiter unten. Der Browser scrollt das Ziel sichtbar in den Ausschnitt.
Zum InhaltNavigationHauptinhalt
inhalt.focus()Scrollen: Browser
JS

focus() setzt document.activeElement

Das Skript wählt das Ziel und entscheidet, ob der Browser dorthin scrollt.

CSS

:focus oder :focus-visible zeichnet den Rahmen

Die Pseudoklasse ändert keine Fokusposition. Sie macht den Zustand nur sichtbar.

Scrollentscheidung

Das Ziel bestimmt die Option

Ohne Option scrollt focus() das Ziel in den sichtbaren Bereich. Verwenden Sie preventScroll: true, wenn die Ebene bereits im Blick liegt oder ein eigener Scrollschritt folgt.

focus()Fokus + Scrollen
focus({ preventScroll: true })Fokus, Ausschnitt bleibt
1

Fehlerzusammenfassung

Die Meldung wird sichtbar, erhält den Fokus und darf in den Bildausschnitt rücken. :focus zeigt die Landung auch nach einem Zeigerklick.

<form id="konto" novalidate>
  <p id="mail-fehler" tabindex="-1" hidden>
    Bitte tragen Sie eine E-Mail-Adresse ein.
  </p>
  <label for="mail">E-Mail-Adresse</label>
  <input id="mail" type="email" required>
  <button type="submit">Konto anlegen</button>
</form>

<style>
  #mail-fehler:focus {
    outline: 3px solid #3b2bbd;
    outline-offset: 3px;
  }
</style>

const form = document.querySelector('#konto');
const mail = document.querySelector('#mail');
const fehler = document.querySelector('#mail-fehler');

form.addEventListener('submit', (event) => {
  if (mail.validity.valid) return;
  event.preventDefault();
  fehler.hidden = false;
  fehler.focus();
});
2

Modaldialog

Der Titel erklärt den Kontext. Beim Schließen geht der Fokus zum Öffner zurück. Beide Ziele liegen im Blick, deshalb bleibt der Bildausschnitt stehen.

<button id="oeffnen" type="button">Warenkorb</button>
<dialog id="dialog" aria-labelledby="dialog-titel">
  <h2 id="dialog-titel" tabindex="-1">Bestellung prüfen</h2>
  <button id="schliessen" type="button">Schließen</button>
</dialog>

const dialog = document.querySelector('#dialog');
const titel = document.querySelector('#dialog-titel');
const oeffnen = document.querySelector('#oeffnen');
const schliessen = document.querySelector('#schliessen');

oeffnen.addEventListener('click', () => {
  dialog.showModal();
  titel.focus({ preventScroll: true });
});

schliessen.addEventListener('click', () => dialog.close());
dialog.addEventListener('close', () => {
  oeffnen.focus({ preventScroll: true });
});
3

Sprungziel

Der Link aktualisiert das Fragment. Im nächsten Frame übernimmt der Hauptbereich den Fokus. Ohne preventScroll kommt das entfernte Ziel ins Bild.

<a id="sprung" href="#inhalt">Zum Inhalt</a>
<nav aria-label="Hauptnavigation">…</nav>
<main id="inhalt" tabindex="-1">
  <h1>Seitentitel</h1>
</main>

const sprung = document.querySelector('#sprung');
const inhalt = document.querySelector('#inhalt');

sprung.addEventListener('click', () => {
  requestAnimationFrame(() => inhalt.focus());
});

So prüfen Sie es

Beobachten Sie Fokus, Rahmen und Scrollposition getrennt

  1. FokuspunktLesen Sie nach jeder Aktion document.activeElement aus.
  2. MarkierungLösen Sie jeden Weg mit Tastatur und Zeiger aus. Das Ziel bleibt erkennbar.
  3. AusschnittDas Ziel liegt vollständig im Bild; kein unnötiger Sprung bewegt den Hintergrund.
  4. WeiterwegTab führt vom neuen Fokus logisch weiter, Escape oder Schließen führt zurück.

Aus dem Prüfbericht

Ein Befund am Fokusziel

Zum Mitnehmen

Der Fokussprung, korrigiert

focus() bewegt den Fokus, CSS zeigt ihn, ARIA darf ihn nicht verstecken.

Korrektur in 3 Schritten ansehen
  1. Die Ausblendung am Container entfernen

    Ein Bereich mit aria-hidden bleibt sichtbar und anspringbar, aber stumm. Als Ziel eines Fokussprungs gehört das Attribut weg.

    KorrekturvergleichSchritt 1 · HTML

    Vorher

    <div id="formular-fehler" aria-hidden="true" tabindex="-1">
      <p>Bitte tragen Sie eine E-Mail-Adresse ein.</p>
    </div>

    Nachher

    <div id="formular-fehler" tabindex="-1">
      <p>Bitte tragen Sie eine E-Mail-Adresse ein.</p>
    </div>

    Markierte Zeilen wurden geändert

    So prüfen Sie es Senden Sie das Formular leer ab. Ein Vorleseprogramm liest die Fehlermeldung vor.

  2. Den Fokus im Skript setzen

    Das Attribut tabindex mit minus eins macht den Textblock per Skript fokussierbar, ohne ihn in den Tab-Weg zu stellen.

    KorrekturvergleichSchritt 2 · JavaScript

    Vorher

    formular.addEventListener('submit', (ereignis) => {
      ereignis.preventDefault();
      fehler.hidden = false;
    });

    Nachher

    formular.addEventListener('submit', (ereignis) => {
      ereignis.preventDefault();
      fehler.hidden = false;
      fehler.focus();
    });

    Markierte Zeilen wurden geändert

    So prüfen Sie es Senden Sie leer ab und drücken Sie Tab. Es geht bei der Meldung weiter, nicht am Seitenanfang.

  3. Die Markierung sichtbar halten

    Bei Tastaturbedienung zeigt focus-visible den Rahmen. Ein per Skript fokussiertes Meldungsziel markieren Sie mit focus auch nach einem Zeigerklick.

    KorrekturvergleichSchritt 3 · CSS

    Vorher

    #formular-fehler:focus {
      outline: none;
    }

    Nachher

    #formular-fehler:focus {
      outline: 3px solid #3b2bbd;
      outline-offset: 3px;
    }

    Markierte Zeilen wurden geändert

    So prüfen Sie es Lösen Sie den Fehler mit Tastatur und Zeiger aus. Ein Rahmen umschließt die Meldung.

Werbung

Kostenloser Website-Barrierefreiheits-Check

Website auf Barrierefreiheit prüfen.

Technische WCAG-Warnsignale erkennen. Kritische Stellen zuerst prüfen.

Der Website-Check ist bereit.

Werbung

Ein letzter Schritt

Prüfen, bevor Sie gehen.

Finden Sie automatisch erkennbare Barrieren auf Ihrer eigenen Website.

Website prüfen

Kostenlos starten · keine Installation

Automatisches Screening. Tastaturbedienung und Screenreader bleiben manuelle Prüfung.