Viele Arten von assistiven Technologien nutzen die Tastaturnavigation, um Bildschirminhalte zu verstehen und darauf zu reagieren. Eine Navigationsmethode ist die Tabulator-Taste. Sie sind damit vielleicht bereits vertraut, wenn Sie sie verwenden, um schnell von einem Eingabefeld zum nächsten in einem Formular zu springen, ohne zur Maus oder zum Trackpad greifen zu müssen.
Die Tabulator-Taste springt zu interaktiven Elementen in der Reihenfolge, in der sie im DOM erscheinen. Dies ist einer der Gründe, warum es so wichtig ist, dass die Reihenfolge Ihres Quellcodes mit der visuellen Hierarchie Ihres Designs übereinstimmt.
Die Liste der interaktiven Elemente, die per Tabulator erreichbar sind, umfasst:
- Anker-Tags, wenn das Attribut
hrefvorhanden ist, <button>,<input>und<textarea>, mit einem zugehörigen Label,<select>,<details>,<audio>und<video>, wenn Steuerelemente vorhanden sind,<object>, je nachdem, wie es verwendet wird,- jedes Element mit Scroll-Überlauf in Firefox,
- jedes Element, auf das das Attribut
contenteditableangewendet wurde, und - jedes Element, auf das das Attribut
tabindexangewendet wurde (mehr dazu gleich).
Ein interaktives Element erhält den Fokus, wenn
- es über die Tabulator-Taste angesteuert wurde,
- es angeklickt wird, nachdem ein Link zu einem anderen fokussierbaren Element,
- oder der Fokus programmgesteuert über
element.focus()in JavaScript gesetzt wird.
Der Fokus ist analog zum Überfahren eines Elements mit dem Mauszeiger, insofern als Sie das Element identifizieren, das Sie aktivieren möchten. Er ist auch der Grund, warum visuell erkennbare Fokusstile so wichtig sind.
Fokusmanagement
Fokusmanagement ist die Praxis, zu koordinieren, was Fokusereignisse empfangen kann und was nicht. Es ist eine der kniffligeren Aufgaben in der Frontend-Entwicklung, aber wichtig, um Websites und Webanwendungen zugänglich zu machen.
Gute Praktiken für das Fokusmanagement
99% der Zeit wollen Sie die Fokusreihenfolge unverändert lassen. Das kann ich gar nicht genug betonen.
Der Fokus funktioniert einfach für Sie, ohne dass zusätzliche Anstrengungen erforderlich sind, vorausgesetzt, Sie verwenden das Element <button> für Schaltflächen, das Anker-Element für Links, das Element <input> für Benutzereingaben usw.
Es gibt seltene Fälle, in denen Sie möglicherweise den Fokus auf etwas außerhalb der Fokusreihenfolge legen oder etwas, das normalerweise keine Fokusereignisse empfangen kann, fokussierbar machen möchten. Hier sind einige Richtlinien, wie Sie dies auf zugängliche, intuitive Weise tun können
✅ Tun Sie es: Lernen Sie das Attribut tabindex kennen
tabindex ermöglicht es einem Element, den Fokus zu erhalten. Es akzeptiert eine ganze Zahl als Wert. Sein Verhalten ändert sich je nachdem, welche ganze Zahl verwendet wird.
❌ Tun Sie es nicht: Wenden Sie tabindex="0" auf Dinge an, die es nicht brauchen
Interaktive Elemente, die den Tastaturfokus erhalten können (wie das Element <button>), müssen das Attribut tabindex nicht auf sie anwenden.
Zusätzlich müssen Sie tabindex nicht auf nicht-interaktiven Elementen deklarieren, um sicherzustellen, dass sie von assistiver Technologie gelesen werden können (tatsächlich ist dies ein WCAG-Fehler, wenn keine Rolle und kein zugänglicher Name vorhanden ist). Dies zu tun, schafft tatsächlich eine unerwartete und schwer zu navigierende Erfahrung für jemanden, der assistierende Technologie nutzt – diese Person hat andere, erwartete Wege, um diesen Inhalt zu lesen.
✅ Tun Sie es: Verwenden Sie tabindex="-1", um mit JavaScript den Fokus zu setzen
tabindex="-1" wird verwendet, um mit JavaScript zugängliche interaktive Widgets zu erstellen.
Eine Deklaration von tabindex="-1" macht ein Element per JavaScript oder durch Klicken/Tippen fokussierbar. Es lässt sich jedoch nicht über die Tabulator-Taste ansteuern.
❌ Tun Sie es nicht: Verwenden Sie eine positive ganze Zahl als tabindex-Wert
Dies ist ein ernsthaftes Anti-Muster. Die Verwendung einer positiven ganzen Zahl überschreibt die erwartete Tabulatorreihenfolge und schafft eine verwirrende und desorientierende Erfahrung für die Person, die versucht, durch Ihren Inhalt zu navigieren.
Eine einzelne Instanz davon ist schon schlimm genug. Mehrere Deklarationen sind ein Albtraum. Ernsthaft: tun Sie es nicht.
❌ Tun Sie es nicht: Erstellen Sie eine manuelle Fokusreihenfolge
Interaktive Elemente können einfach durch ihre Verwendung per Tabulator erreicht werden. Sie müssen keine Reihe von tabindex-Attributen mit inkrementierenden Werten für jedes interaktive Element in der von Ihnen gewünschten Reihenfolge festlegen. Stattdessen überlassen Sie dies der Reihenfolge der Elemente im DOM.
Fokus-Trapping
Es kann vorkommen, dass Sie verhindern müssen, dass Dinge fokussiert werden. Ein gutes Beispiel dafür ist Fokus-Trapping, das ist die bedingte Beschränkung von Fokusereignissen auf ein Element und seine Kindelemente.
Fokus-Trapping darf nicht mit Keyboard-Fallen (manchmal als Fokus-Fallen bezeichnet) verwechselt werden. Keyboard-Fallen sind Situationen, in denen jemand, der mit der Tastatur navigiert, ein Widget oder eine Komponente nicht verlassen kann, da eine störende Schleife aus schlecht geschriebener Logik vorhanden ist.
Ein praktisches Beispiel dafür, wofür Sie Fokus-Trapping verwenden würden, wäre ein Modalfenster
Warum ist es wichtig?
Das Halten des Fokus innerhalb eines Modalfensters kommuniziert seine Grenzen und hilft zu informieren, was Modalinhalt ist und was nicht – es ist analog dazu, wie eine sehende Person sehen kann, wie ein Modalfenster über anderen Website- oder Webanwendungsinhalten "schwebt". Dies sind wichtige Informationen, wenn:
- Sie haben geringe oder keine Sehkraft und verlassen sich auf Screenreader-Ankündigungen, um die Änderung des Interaktionsmodus zu vermitteln.
- Sie haben geringe Sehkraft und ein vergrößertes Display, wobei der Fokus außerhalb der Grenzen des Modalfensters verwirrend und desorientierend sein kann.
- Sie navigieren ausschließlich per Tastatur und könnten sonst aus dem Modalfenster heraus tabben und sich auf der zugrunde liegenden Seite oder Ansicht verirren, um wieder in das Modalfenster zu gelangen.
Wie macht man das?
Zuverlässiges Fokusmanagement ist eine komplizierte Angelegenheit. Sie müssen JavaScript verwenden, um
- die Container-Elemente aller fokussierbaren Elemente auf der aktuellen Seite oder Ansicht zu bestimmen.
- die Grenzen des gefangenen Inhalts zu identifizieren, einschließlich des ersten und letzten fokussierbaren Elements.
- sowohl Interaktivität als auch Auffindbarkeit von allem zu entfernen, was als fokussierbar identifiziert wurde, aber nicht innerhalb dieses gefangenen Inhalts liegt.
- den Fokus in den gefangenen Inhalt zu verschieben.
- auf Ereignisse zu hören, die das Schließen des gefangenen Inhalts signalisieren (Speichern, Abbrechen, Schließen/Drücken der Esc-Taste usw.).
- den gefangenen Inhaltsbereich zu schließen, wenn er durch ein relevantes Ereignis ausgelöst wird.
- die zuvor entfernte Interaktivität wiederherzustellen.
- den Fokus zurück auf das interaktive Element zu verschieben, das den gefangenen Inhalt ausgelöst hat.
Warum machen wir das?
Ich werde nicht lügen: Das alles ist knifflig und zeitaufwendig. Allerdings ist Fokusmanagement und eine sinnvolle, nutzbare Fokusreihenfolge eine Web Content Accessibility Guideline. Es ist wichtig genug, dass es als Teil eines internationalen, rechtlich bindenden Standards für Benutzerfreundlichkeit gilt.
Per Tabulator erreichbar und auffindbar
Es gibt einen kleinen Trick, um sowohl die Auffindbarkeit als auch die Interaktivität zu entfernen.
Screenreader haben einen Interaktionsmodus, der es ihnen ermöglicht, die Seite oder Ansicht über einen virtuellen Cursor zu erkunden. Der virtuelle Cursor ermöglicht es dem Screenreader-Benutzer auch, nicht-interaktive Teile der Seite (Überschriften, Listen usw.) zu entdecken. Im Gegensatz zur Verwendung von Tab und Fokusstilen ist der virtuelle Cursor nur für Benutzer von Screenreadern verfügbar.
Wenn Sie den Fokus verwalten, möchten Sie möglicherweise die Möglichkeit einschränken, dass der virtuelle Cursor Inhalte entdeckt. Für unser Modalfenster-Beispiel bedeutet dies, dass verhindert wird, dass jemand versehentlich aus den Grenzen des Modalfensters "ausbricht", wenn er es liest.
Die Auffindbarkeit kann durch eine gezielte Anwendung von aria-hidden="true" unterdrückt werden. Die Interaktivität ist jedoch etwas nuancierter.
inert betreten
Das Attribut inert ist ein globales HTML-Attribut, das das Entfernen und anschließende Wiederherstellen der Fähigkeit interaktiver Elemente, entdeckt und fokussiert zu werden, erheblich erleichtern würde. Hier ist ein Beispiel, wie es funktionieren würde
<body>
<div
aria-labelledby="modal-title"
class="c-modal"
id="modal"
role="dialog"
tabindex="-1">
<div role="document">
<h2 id="modal-title">Save changes?</h2>
<p>The changes you have made will be lost if you do not save them.<p>
<button type="button">Save</button>
<button type="button">Discard</button>
</div>
</div>
<main inert>
<!-- ... -->
</main>
</body>
Ich vermeide bewusst die Verwendung des Elements <dialog> für das Modalfenster aufgrund seiner vielen Probleme mit der Unterstützung durch assistierende Technologien.
inert wurde auf das Element <main> angewendet, nach einem Modalfenster zur Bestätigung des Speicherns. Das bedeutet, dass alle Inhalte innerhalb von <main> weder den Fokus empfangen noch angeklickt werden können.
Der Fokus ist auf das Innere des Modalfensters beschränkt. Wenn das Modalfenster geschlossen wird, kann inert vom Element <main> entfernt werden. Diese Art der Behandlung von Fokus-Trapping ist im Vergleich zu bestehenden Techniken weitaus einfacher.
Denken Sie daran: Ein Schließungsereignis kann durch die beiden Schaltflächen innerhalb unseres Modalfenster-Beispiels ausgelöst werden, aber auch durch Drücken von Esc auf Ihrer Tastatur. Einige Modalfenster lassen Sie auch außerhalb des Modalbereichs klicken, um sie zu schließen.
Unterstützung für inert
Die neuesten Versionen von Edge, Chrome und Opera unterstützen inert, wenn experimentelle Webplattformfunktionen aktiviert sind. Firefox-Unterstützung wird ebenfalls bald eintreffen! Der einzige Ausreißer sind sowohl Desktop- als auch mobile Versionen von Safari.
Ich würde mir wünschen, dass Apple die native Unterstützung für inert implementiert. Obwohl ein Polyfill verfügbar ist, hat es nicht-triviale Support-Probleme für alle wichtigen Screenreader. Nicht gut!
Darüber hinaus möchte ich auf diese Notiz aus der README-Datei des inert-Polyfill-Projekts hinweisen.
Der Polyfill wird im Vergleich zu einer nativen
inert-Implementierung leistungsmäßig teuer sein, da er eine beträchtliche Menge an Tree-Walking erfordert.
Tree-Walking bedeutet, dass die JavaScript-Datei im Polyfill potenziell viel Rechenleistung benötigt, um zu funktionieren, und daher die Benutzererfahrung des Endbenutzers verlangsamt.
Für Geräte mit geringerer Leistung, wie z. B. günstige Android-Smartphones, ältere Laptops und leistungsfähigere Geräte, die rechenintensive Aufgaben ausführen (wie z. B. das Ausführen mehrerer Electron-Apps), kann dies zum Einfrieren oder Abstürzen führen. Native Browser-Unterstützung bedeutet, dass diese Art von Verhalten für das Gerät weniger belastend ist, da sie auf Teile des Browsers zugreifen kann, auf die JavaScript keinen Zugriff hat.
Safari
Persönlich bin ich von Apples mangelnder Unterstützung für inert enttäuscht. Obwohl ich verstehe, dass das Hinzufügen neuer Funktionen zu einem Browser extrem kompliziert und schwierig ist, scheint inert eine Funktion zu sein, die Apple viel früher hätte unterstützen sollen.
macOS und iOS hatten historisch gesehen eine hervorragende Unterstützung für Barrierefreiheit, und assistiven Technologien freundliche Funktionen sind ein üblicher Bestandteil ihrer Marketingkampagnen. Die Unterstützung von inert scheint eine natürliche Erweiterung von Apples Mission zu sein, da die Funktion selbst viel dazu beitragen würde, zugängliche Weberfahrungen einfacher zu entwickeln.
Frustrierenderweise hält sich Apple auch bedeckt, woran sie arbeiten und wann wir damit rechnen können. Aus diesem Grund ist die Zukunft von inert eine offene Frage.
Igalia
Igalia ist ein Unternehmen, das an Browserfunktionen arbeitet. Sie haben derzeit ein Experiment, bei dem die Öffentlichkeit abstimmen kann, welche Funktionen sie sehen möchten. Die Begründung für diese Initiative liegt außerhalb des Rahmens dieses Artikels, aber Sie können mehr darüber auf Smashing Magazine lesen.
Eine Funktion, die Igalia in Betracht zieht, ist die Hinzufügung von WebKit-Unterstützung für inert. Wenn Sie nach einer Möglichkeit gesucht haben, die Barrierefreiheit im Web zu verbessern, aber unsicher waren, wie Sie anfangen sollen, ermutige ich Sie, eine Spende zu tätigen. 5 $, 10 $, 25 $. Es muss kein großer Betrag sein, jeder kleine Beitrag zählt.
Leider hat inert das Open Prioritization-Experiment nicht gewonnen. Das bedeutet, wir wissen wieder nicht, ob Apple daran arbeitet oder wann wir es in Safari Technology Preview erwarten können.
iOS 15.4 wird mit deaktivierter Unterstützung für das Attribut inert ausgeliefert. Das sind tolle Neuigkeiten, da es signalisiert, dass Apple daran arbeitet.
Zusammenfassung
Fokusmanagement erfordert Geschick und Sorgfalt, ist aber sehr lohnenswert. Das Attribut inert kann wesentlich dazu beitragen, dies zu erleichtern.
Technologien wie inert stellen auch eine der größten Stärken der Webplattform dar: die Fähigkeit, die ausgetretenen Pfade zu pflastern und sie in etwas Einfaches und Effektives zu kodifizieren.
Weitere Lektüre
- Fokus mit tabindex steuern (A11ycasts, Folge 04)
- Verwendung des tabindex-Attributs (The Paciello Group)
- JavaScript verwenden, um den Fokus in einem Element zu sperren (Hidde de Vries)
Vielen Dank an Adrian Roselli und Sarah Higley für ihr Feedback.
Ich bin der Meinung, dass wir Igalia und seine Initiative nicht fördern sollten.
Apple ist bei weitem der schlimmste Übeltäter bei der Unterstützung von Browserfunktionen und ist das reichste Unternehmen der Welt... Wir müssen nicht dafür bezahlen, dass jemand anderes eine Funktion zu Safari hinzufügt. Apple muss sich von seinem faulen Hintern lösen und die Arbeit tatsächlich erledigen.
Was den beliebtesten Browser, Chrome, betrifft, so treiben sie tatsächlich viele neue Standards voran, was gut ist. Aber wir müssen dort auch nichts extra bezahlen. Sie gehören definitiv zur obersten Liga der Marktkapitalisierung, sie sind dreist reich genug...
Edge ist großartig, der Wechsel zu Chromium hat ihnen sehr geholfen, wenn auch ein wenig unglücklich für Webstandards. Aber auch hier ist es nicht so, dass Microsoft unser Geld braucht, sie gehören ebenfalls zur obersten Liga, ganz nah an Apple.
Wenn Sie wirklich das Web fördern wollen, fördern Sie Firefox. Google hat sie ausgetrocknet, indem sie einige ihrer Ingenieure eingestellt und ihren eigenen Browser gebaut haben, während sie einen großen Teil ihrer Finanzierung für Firefox gekürzt haben...
Es wäre mir egal, wenn Igalia nicht an Browsern von Unternehmen arbeiten würde, die über 1 Billion Dollar wert sind... Aber so wie es jetzt ist, kann ich keinen Grund finden, ihnen in irgendeiner Weise zu helfen.
Absolut einverstanden.
Und ein Pluspunkt von mir für Firefox. Ich benutze ihn, seit er herauskam, und er ist immer noch mein bevorzugter Browser.
Hallo Eric, vielen Dank für diese Präsentation.
Wissen Sie, warum das Hinzufügen von
inertzu jedem Element, um es kurzzeitig als nicht erkennbar und nicht interaktiv zu markieren, der Hinzufügung eines einzigen Attributs zum Element vorgezogen wurde, um es (kurzzeitig) als das einzige Element des Dokuments zu markieren, das erkennbar und interaktiv sein sollte?Als Alternative zu einer Funktion wie
inert, die noch nicht gut über Browser hinweg unterstützt wird, ist es relativ einfach, den Fokus zu sperren, indem man einenkeydown-Handler am Container-Element des Widgets (z. B. demdiv-Dialog im Beispiel) installiert und die Tabulator- (und Shift-Tabulator!) Taste verarbeitet. Dietarget-Eigenschaft des Ereignisses gibt an, welches Element den Fokus hatte, als die Taste gedrückt wurde. Der Ereignis-Handler muss nur wissen, welche interaktiven Elemente im Widget „erste“ und „letzte“ in der Tabulatorreihenfolge sind, und wenn eines dieser Elemente dastargetist, musselement.focus()verwendet werden, um den Fokus auf das entsprechende „nächste“ Element zu verschieben; andernfalls nichts tun und das Ereignis weiterleiten lassen.Da die meisten komplexen Widgets, die Fokusbehandlung benötigen, andere Schlüsselbehandlungsanforderungen haben, ist es nicht viel mehr Arbeit, auch die Tabulatorbehandlung einzubeziehen. Und dies begrenzt die Fokusbehandlung auf nur die Elemente innerhalb des Widgets, anstatt das DOM außerhalb des Widgets ändern zu müssen.
Und der virtuelle Cursor eines Screenreaders? Würde ein Keydown-Handler das auch tun?
Eine weitere Möglichkeit, Fokus-Trapping zu implementieren, ist die Verwendung von 2 Trappern als erste und letzte tabulatorische Elemente innerhalb des Trapping-Inhaltscontainers, z. B.
In JS
Ich hätte einen Opt-in-Ansatz für Fokus-Trapping bevorzugt, wie z. B. das Attribut
modal, das, wenn es vorhanden ist, den Fokus innerhalb des umschließenden Elements einfängt.Aus der Sicht eines Komponentenautors, woher weiß ein Dialog, welches Element/welche Elemente
inertwerden sollen, wenn der Dialog aktiviert wird? Er kann es nicht wissen. Aber er könntemodalan sich anhängen und das Problem auf elegante Weise lösen.