Der Anlass für diesen Artikel war mal wieder ein Beispiel, das aus dem Leben gegriffen ist. Ich testete am Montag browserid.org auf Barrierefreiheit und stieß auf einige Ungereimtheiten bei der Tastatur- und ScreenReader-Bedienung.

Zum einen gibt es sowohl oberhalb der zu einem Konto gehörigen E-Mail-Adressen als auch neben der Überschrift zum Ändern des Passworts „Edit“-Buttons, deren Funktionalität sich mir nicht erschließen wollte. Denn für meinen Screen Reader waren die „Remove“-Buttons neben den E-Mail-Adressen bzw. die Felder fürs alte und neue Passwort auch ohne Betätigen dieser „Edit“-Buttons sichtbar, und die Aktionen konnten ohne weiteres ausgeführt werden. Zum anderen erschloss sich mir auch beim Durchnavigieren der Seite mit Tab nicht, welchen Unterschied diese „Edit“-Buttons machen sollten.

Die Lösung ergab sich erst, als ich meine Lebensgefährtin bat, sich diese Seite mit mir zusammen anzuschauen. Für sie war nach dem ersten Laden keiner der „Remove“-Buttons oder die Eingabefelder für die Passwörter sichtbar. Als ich anfing, mit dem virtuellen Cursor von NVDA hindurchzunavigieren, erschienen plötzlich die Buttons und Eingabefelder. Wanderte ich rückwärts, verschwanden sie wieder. Navigierte ich mit Tab, erschienen sie und blieben sichtbar.

Das „Verstecken“ der Inhalte wurde hier also auf eine Weise erledigt, die die Inhalte zwar für Sehende versteckte, für Screen Reader aber nicht. Weiterhin wurde nicht berücksichtigt, dass sich für Tastaturbenutzer ein anderes Interaktionsmodell ergibt als für Mausbenutzer. Es wurde die falsche Technik zum Verstecken von Inhalten angewandt.

Ich will mal versuchen, ein bisschen Licht ins Dunkel zu bringen und gleichzeitig ein paar grundsätzliche Missverständnisse aufzuklären, mit denen ich seit über 10 Jahren immer wieder konfrontiert werde.

Die Grundlage 🔗

Zum Verständnis unbedingt erforderlich ist das Folgende: Screen Reader und andere assistive Technologien für Menschen mit Behinderungen nutzen eine Sammlung von Objekten, die den Inhalt einer Webseite widerspiegelt, um dem Anwender den Zugang hierzu ermöglichen. Diese Objekte sind hierarchisch gegliedert, wie in einem Baum. Der Stamm ist das Dokument, die Kindelemente sind vielleicht einzelne Sektionen, Überschriften, navigationsblöcke usw. Dieser Baum stellt eine Untermenge des durch den HTML-Code der Seite erstellten Baums des Document Object Model (DOM) des Browsers dar. Da die Objekte für Barrierefreiheit nicht für jedes Element eine Entsprechung benötigen, ist die Abbildung nicht ganz 1:1. In Fachkreisen wird diese Untermenge als Accessible Tree bezeichnet. Die Browser-Engine, z. B. Gecko bei Mozilla-basierten Browsern, versieht diese Objekte jedoch mit weiteren Eigenschaften, die für den Menschen mit Behinderung unbedingt notwendig sind.

Hierzu werden nicht nur die Informationen aus den Attributen des jeweiligen HTML-Tags herangezogen, sondern auch Stilinformationen. So werden Informationen zu Textattributen aus dem CSS abgeleitet, Farben usw. ebenfalls daraus ermittelt.

Einige Eigenschaften werden nicht berücksichtigt, z. B. die letztendliche Positionierung einzelner Elemente. Ein Div-Container kann also z. B. auf der Startseite oben rechts in der Ecke neben der Navigation angezeigt werden, der Screen Reader wird ihn jedoch an der Stelle des Dokumentflusses anzeigen, an dem er im Quelltext steht. Die Positionierung per CSS hat auf die Lesereihenfolge des Screen Readers keinen Einfluss. Siehe hierzu auch diesen Eintrag von mir, in dem ich das am Beispiel einer Lightbox erkläre.

Verstecken ist nicht gleich verstecken 🔗

Einige CSS-Anweisungen werden jedoch strikt befolgt. Im IE macht dies der Screen Reader, bei Firefox macht es die Gecko-Engine schon vorab. Und dies ist schon seit über 10 Jahren so. Elemente, die mit „display: none;“ oder „visibility: hidden;“ gestylt werden, werden nicht mit in den Accessible Tree aufgenommen. Erst wenn sich z. B. durch eine JavaScript-Anweisung ihr Styling ändert, werden sie an entsprechender Stelle in den Baum eingefügt, und es wird ein Ereignis ausgelöst, das dem Screen Reader mitteilt, dass hier ein neues Element oder eine Gruppe von Elementen erschienen ist.

Andere Anweisungen zum „Verstecken“ von Elementen wie „left: -9999px; top: -9999px;“ werden hingegen nicht berücksichtigt. Diese Elemente sind für Screen Reader genauso sichtbar wie solche, als stünden sie sichtbar fürs Auge auf dem Bildschirm.

Also nochmal, damit’s niemand überliest: Elemente, die mit „display: none;“ oder „visibility: hidden;“ gestylt sind, werden auch vor Screen Reedern immer versteckt! Dies gilt ohne Ausnahme für NVDA, JAWS usw. unter Windows, Orca unter Linux, und VoiceOver auf Mac und iOS. Die letzte JAWS-Version, die das nicht konnte, war, glaube ich, Version 4.02, die im April oder Mai 2001 erschien. Seitdem machen das alle alle alle JAWS-Versionen und alle anderen Screen Reader, die ich kenne, richtig. Warum sich ein das Gegenteil behauptendes Gerücht bis heute so hartnäckig in der Webentwickler-Szene hält, ist mir ein absolutes Rätsel. „display: none;“ oder „visibility: hidden;“ eigenen sich also nicht, um dem Screen Reader Zusatzinhalte anzubieten. Er wird sie schnöde ignorieren!

Wann verwende ich denn nun was? 🔗

Sobald Elemente tatsächlich erst sichtbar werden sollen, wenn eine bestimmte Aktion bewusst ausgeführt wird, sollten, je nach Bedarf, „display: none;“ oder „visibility: hidden;“ verwendet werden. Ein Anwendungsbeispiel, das viele Blogger jedesmal vor der Nase haben, wenn sie selbst einen Beitrag schreiben, ist das Administrations-Backend von WordPress. Die Hauptmenüpunkte „Dashboard“, „Artikel“ usw. verbergen ihre Untermenüs durch das Stylen mit einer dieser beiden CSS-Anweisungen. Erst wenn der Anwender entweder mit der Maus rüberfährt oder mit Tab drauf navigiert und Enter drückt, wird der Style entsprechend geändert, und die Untermenüpunkte erscheinen. Richtigerweise wird auf dem Hauptmenüpunkt auch das WAI-ARIA-Attribut aria-haspopup=“true“ wird richtig gesetzt, so dass man sofort mitgeteilt bekommt, dass hier ein Untermenü vorliegt.

Würde hier mit einem lediglich aus dem sichtbaren Bereich verschobenen Container gearbeitet, würde ich die ganzen Untermenü-Punkte mit meinem Screen Reader zu sehen bekommen. Sämtliche Vorteile eines aufgeräumteren Interfaces wären für mich dahin. Ja, auch ich genieße die Vorzüge dynamischer Interfaces, in denen ich ein- und ausblenden kann, was ich zur zeit zum Arbeiten brauche und was nicht! Ist das entsprechende Markup vorhanden, muss ich nicht zwingend sofort sämtlichen verfügbaren Inhalt sehen. Der macht auch für mich ein Interface unaufgeräumt, unübersichtlich und schwer navigierbar!

Der falsche Weg ist der, den ich am Anfang des Artikels beschrieben habe. Die Buttons und Passwort-Felder im Kontobereich von BrowserID wurden lediglich aus dem sichtbaren Bereich verschoben, nicht wirklich versteckt.

Eine sinnvolle Anwendung von aus dem sichtbaren Bereich verschobenen Elementen ist die Verwendung sogenannter Skip Links. Dirk Jesse hat hierzu einen vorzüglichen Blogeintrag verfasst, dessen Lektüre ich dem geneigten Leser wärmstens ans Herz legen möchte! Auch dort wird kurz darauf verwiesen, wofür „display: none;“ der völlig falsche Weg ist.

Fazit 🔗

Ich hoffe, dieser Artikel kann dazu beitragen, einige Verwirrung aufzulösen, die um die Verwendung von „display: none;“ und negativer Positionierung besteht, wann was angewendet werden sollte und wann nicht. Die Faustregel ist: Soll etwas komplett versteckt und erst nach einer bewussten Aktion eingeblendet werden, „echt“ verstecken. Soll etwas grundsätzlich für Screen Reader erreichbar sein, ohne dass man vorher eine Aktion ausführen muss, dieses Element aber nicht zwangsläufig sofort sichtbar sein, verwendet man negative Positionierung. Aber dabei auch immer schön an die Tastaturbenutzer ohne Screen Reader denken und die Elemente rechtzeitig einblenden! 😉

Fragen? Die gibt es bestimmt! Immer her damit, denn nur „wer nicht fragt, bleibt dumm“, das wissen wir ja schon seit der Sesamstraße! 🙂