Accessible Modal
Der Dialog, der den Fokus hält
Fokus hinter dem Dialog, Schließen ohne Namen: zwei Befunde in einem Fenster.
Fokusweg im Bild
Öffnen. Im Dialog bleiben. Sicher zurückkehren.
Ein modaler Dialog ist erst vollständig, wenn sein Fokusweg verständlich bleibt.
Der Fokusweg in drei Zuständen
sichtbarer Tastaturfokus
Vor dem Öffnen
MONATSPOSTFokus auf dem AuslöserEnter aktiviert den echten
<button>. Der Auslöser bleibt als Rückkehrziel erhalten.Während des Dialogs
MONATSPOSTinert: kein Klick, kein SeitenfokusDialogNewsletter abonnierenEine Ausgabe pro Monat.E-Mail-AdresseTab und Umschalt + Tab: nur DialoginhaltshowModal()setzt den Dialog in den Top Layer. Der übrige Inhalt desselben Dokuments wird inert.Nach dem Schließen
Escape oder „Abbrechen“Fokus wieder auf dem AuslöserBeim nativen modalen Dialog gibt der Browser den Fokus an den noch vorhandenen Auslöser zurück.
Was showModal() übernimmt
- Top Layer: Der Dialog liegt über dem Dokument.
- Inert: Die Seite dahinter ist nicht bedienbar.
- Fokus: Er wechselt in den Dialog und kehrt beim Schließen zum vorhandenen Auslöser zurück.
- Escape: Die Taste fordert das Schließen über das
cancel-Ereignis an.
Was Sie festlegen
- Name:
aria-labelledbyverweist auf die Überschrift. - Start:
autofocusmarkiert das passende erste Ziel. - Ausgang: Eine sichtbare Schaltfläche schließt den Dialog.
- Sonderfall: Fehlt der Auslöser danach, wählen Sie ein logisches Rückkehrziel im Ablauf.
Vollständige, kleine Vorlage
Das Formular sendet die Anmeldung. JavaScript öffnet modal und schließt über die sichtbare Abbrechen-Schaltfläche.
<button type="button" id="newsletter-oeffnen">
Newsletter abonnieren
</button>
<dialog id="newsletter" aria-labelledby="newsletter-titel">
<form action="/newsletter" method="post">
<h2 id="newsletter-titel">Newsletter abonnieren</h2>
<p>Eine Ausgabe pro Monat. Abmeldung in jeder E-Mail.</p>
<label for="newsletter-mail">E-Mail-Adresse</label>
<input id="newsletter-mail" name="mail" type="email" required
autocomplete="email" autofocus>
<button type="submit">Eintragen</button>
<button type="button" id="newsletter-schliessen">Abbrechen</button>
</form>
</dialog>
<style>
dialog {
max-width: 32rem;
border: 2px solid currentColor;
padding: 1.5rem;
}
dialog::backdrop { background: rgb(0 0 0 / 0.55); }
:focus-visible { outline: 3px solid #3b2bbd; outline-offset: 3px; }
</style>
<script>
const dialog = document.getElementById('newsletter');
const oeffner = document.getElementById('newsletter-oeffnen');
const schliesser = document.getElementById('newsletter-schliessen');
oeffner.addEventListener('click', () => {
dialog.showModal();
});
schliesser.addEventListener('click', () => {
dialog.close();
});
</script>Prüfen Sie den Weg, nicht nur das Markup
- Öffnen Sie per Tastatur. Der Fokus steht im E-Mail-Feld.
- Tabben Sie vorwärts und rückwärts. Kein Element der Seite dahinter erhält Fokus.
- Schließen Sie mit Escape und erneut über „Abbrechen“. Der Fokus steht jeweils wieder auf „Newsletter abonnieren“.
- Prüfen Sie mit einem Screenreader, ob „Newsletter abonnieren“ als Dialogname ausgegeben wird.
Aus dem Prüfbericht
Zwei Stellen, zwei Befunde
Kritisch Das × hat keinen Namen Regel button-name
Die Schließen-Schaltfläche zeigt nur ein Zeichen. aria-label="Dialog schließen" gibt ihr den Namen.
Zum Mitnehmen
Der Dialog, korrigiert
Ein dialog-Element und showModal() ersetzen die ganze Fokus-Logik.
Korrektur in 2 Schritten ansehen
Das dialog-Element mit showModal() öffnen
showModal() macht alles hinter dem Dialog inert, fängt den Fokus und schließt mit Escape.
KorrekturvergleichSchritt 1 · HTML Vorher
<div class="modal" role="dialog"> <h2>Newsletter abonnieren</h2> <button type="button" class="close">×</button> </div>Nachher
<dialog id="newsletter" aria-labelledby="newsletter-titel"> <h2 id="newsletter-titel">Newsletter abonnieren</h2> <button type="button" class="close" aria-label="Dialog schließen"> <span aria-hidden="true">×</span> </button> </dialog>Markierte Zeilen wurden geändert
So prüfen Sie es Drücken Sie im offenen Dialog mehrmals Tab. Der Fokus bleibt im Dialog.
Öffnen, schließen, Fokus zurückgeben
Der Browser merkt sich den Auslöser. Nach dem Schließen setzt JavaScript den Fokus dorthin zurück.
KorrekturvergleichSchritt 2 · JavaScript Vorher
opener.addEventListener('click', () => { modal.classList.add('open'); page.setAttribute('aria-hidden', 'true'); });Nachher
const dialog = document.getElementById('newsletter'); opener.addEventListener('click', () => dialog.showModal()); dialog.querySelector('.close').addEventListener('click', () => dialog.close()); dialog.addEventListener('close', () => opener.focus());Markierte Zeilen wurden geändert
So prüfen Sie es Schließen Sie den Dialog mit Escape. Der Fokus steht wieder auf der Schaltfläche, die ihn geöffnet hat.
