Barrierefreie Akkordeons
Mit einem Akkordeon lassen sich nebensächliche Inhalte für bessere Übersichtlichkeit verstecken, um Benutzer nicht mit zu vielen Inhalten zu überfordern. Um es direkt vorweg zu sagen: Ein Akkordeon sollte vorsichtig eingesetzt werden, da es die Zugänglichkeit der Inhalte selbst bei gutem Einsatz umständlicher macht. In vielen Fällen bietet es sich eher an die Inhalte auf mehreren Seiten aufzuteilen.
Die Inhalte eines Akkordeons müssen für alle Benutzer einfach zugänglich sein. Es gibt nicht die eine richtige Variante ein Akkordeon umzusetzen, da dies häufig vom Kontext und den Inhalten abhängt. Was es dabei zu beachten gibt und wie man die Benutzerfreundlichkeit verbessern kann, versuche ich hier zusammenzufassen.
Für alle ungeduldigen hier der Link zu Github mit der Beispiel-Implementierung.
Gestaltung
Akkordeons bestehen aus mehreren Elementen mit jeweils einem Button und zugehörigem aufklappbarem Inhalt. Der Button gilt als Überschrift für die Inhalte des Panels. Wie bei allen interaktiven Elementen sollte der Zustand des Buttons klar erkennbar sein. Dazu gehören:
- Fokus: Es sollte klar erkennbar sein dass ein Button gerade den Fokus hat. Das ist insbesondere für Nutzer die mit der Tastatur navigieren wichtig.
- Geöffnet/Geschlossen: Der Button sollte einen klaren visuellen Indikator haben der anzeigt ob der zugehörige Inhalt sichtbar ist oder nicht. Das kann z.B. ein Plus- oder Minuszeichen sein.
- Bedienbarkeit: Ist der Button nicht bedienbar, z.B. weil immer ein Element geöffnet sein muss, sollte das visuell klar erkennbar sein. Das lässt sich z.B. durch ausgegraute Schrift, ein Icon oder Transparenz erreichen.
Die Inhalte des Panels sollten als zusammengehörig erkennbar sein um vom nächsten Element abgegrenzt zu werden. Das kann z.B. durch einen Rand oder gemeinsame Hintergrundfarbe erreicht werden.
Auf entsprechende Kontraste zwischen Schrift, Icons und Hintergrund sowie skalierbare Schriftgrößen muss geachtet werden.
Beispiel-Implementierung
Um alle Informationen zum Status des Akkordeons auch für Benutzer von Screen-Readern zugänglich zu machen werden semantische HTML-Elemente mit entsprechenden ARIA-Attributen versehen. Um deren Status bei Interaktion zu aktualisieren wird JavaScript verwendet.
Begründung für das verwendete HTML
Das <button>-Element wird von einer Überschrift umschlossen. Viele Benutzer von Screen-Readern nutzen die Überschriften zur Navigation über die Webseite.
Mit dem <section>-Element wird der Inhalt des Akkordeons semantisch als zusammengehörig gekennzeichnet. Dies ist nicht gleichbedeutend mit role="region" welches die Inhalte auch für Screen-Reader als zusammengehörig kennzeichnet. Dafür wird das das <section>-Element mit dem aria-labelledby-Attribut versehen.
Das aria-labelledby-Attribut verweist auf die ID des Buttons. Dadurch wird das <section>-Element zur role="region" und zu einem Landmark zu welchem Benutzer von Screen-Readern direkt springen können, wenn es geöffnet ist. Gleichzeitig werden Benutzer von Screen-Readern darüber informiert wann der Inhalt beginnt und endet und das nächste Element beginnt. Für sehende Benutzer ist dies gleichzusetzen mit einer klaren visuellen Trennung der Akkordeon-Elemente.
Das aria-expanded-Attribut gibt Auskunft darüber ob der zugehörige Inhalt eines Akkordeon-Buttons gerade sichtbar ist oder nicht. Es wird auf true oder false gesetzt. Das ersetzt den visuellen Indikator, wie z.B. ein Plus- oder Minuszeichen, und macht den aktuellen Status auch für Benutzer von Screen-Readern zugänglich.
Das aria-controls-Attribute gibt Auskunft darueber welchen Inhalt ein Button kontrolliert. Das könnte von Benutzern assistiver Technologien genutzt werden um direkt zum Inhalt zu springen oder Auskunft über diesen zu geben. Das Attribut wird nicht von allen Screen-Readern unterstützt oder die Auskunft darüber ist standardmässig deaktiviert. Dennoch sollte es genutzt werden da sich dies in Zukunft ändern könnte.
Wir verstecken Inhalt mit hidden="until-found". Im Gegensatz zu display: none hat das hidden-Attribut semantische Bedeutung. Nutzung von until-found führt dazu dass Inhalte des Akkordeons durch die Browsersuche auffindbar sind. Das funktioniert im Moment aber weder in Firefox noch in Safari. Hier fällt es einfach auf das Standardverhalten des Attributs zurück was für unseren Zweck okay ist.
Google allerdings respektiert das Attribut und kann die Inhalte für den Suchindex nutzen.
Typische Fehler bei der Implementierung
Fehler die ich häufig beobachtet habe versuche ich hier einmal übersichtlich mit Korrekturvorschlägen aufzulisten.
Ein <a> oder interaktiv gemachtes<div>-Element ist kein Ersatz für einen <button>. Zwar kann jedes Element mit role="button" als solcher markiert werden, dann müssen aber auch die korrekte Tastaturbedienbarkeit, der Status und ein sichtbarer Fokus sichergestellt werden.
Zudem werden <a>-Elemente von Screen-Readern anders behandelt. Ein fehlendes href-Attribut fuehrt dazu dass der Link nicht mit der Tastatur erreichbar ist. Aber auch wenn das Attribut gesetzt ist wird es unter Umständen vorgelesen und verwirrt den Benutzer.
Ausserdem sollte das type="button" Attribut gesetzt werden. Da manche Browser sonst von type="submit" ausgehen.
Ein <button> setzt role="presentation" auf alle enthaltenen Elemente. Das bedeutet dass z.B. eine Überschrift in der Accessibiliy API nicht mehr als solche behandelt wird. Benutzer von Screen-Readern können dann nicht mehr direkt zur Überschrift springen und können den Überblick über die Struktur der Inhalte verlieren.
Was wir unbedingt vermeiden wollen ist das Benutzer die z.B. per Tab über Links navigieren den Fokus auf unsichtbaren Elementen haben.
Elemente welche z.B. zu Transition-Zwecken mit opacity: 0 ausgeblendet werden sind weiterhin in der Tab-Reihenfolge der interaktiven Elemente erreichbar und werden von Screen-Readern vorgelesen. Kinderelemente von mit height: 0;width: 0;overflow: hidden; ausgeblendeten Elementen sind ebenfalls erreichbar.
Auch ein aria-hidden="true" verhindert nicht dass Kinderelemente den Fokus erhalten können. Der Inhalt sollte mit display: none, visibility: hidden oder dem hidden-Attribut ausgeblendet werden. In Zukunft könnte auch das inert-Attribut in Verbindung mit aria-hidden interessant werden.
Optimierungen
Wann man Akkordion-Inhalte besser nicht zum Landmark macht
Die Nutzung von role="region" oder <section> mit aria-labelledby ermöglichen es Benutzern von Screen-Readern direkt zu den für sie relevanten Inhalten zu springen indem diese zu Landmarks gemacht werden. Das ist besonders bei Seiten mit vielen Inhalten hilfreich. Allerdings kann eine große Anzahl von Landmarks das Gegenteil bewirken und dem Benutzer die Navigation mittels Landmarks erschweren. Das wird besonders dann problematisch wenn alle Elemente geöffnet sind.
Stattdessen wird dann besser ein einfaches <div>-Element genutzt. Eine sinnvolle Regel zu definieren ist schwierig, aber ich würde ab fünf Elementen oder einer grossen Anzahl anderer Landmarks auf der Seite darauf verzichten. In dem Fall ist es vermutlich eh besser die Inhalte auf mehrere Seiten aufzuteilen.
Bei Akkordeons mit vielen Elementen und kurzen Inhalten bietet sich ein Akkordeon an dass seine Elemente in einer Liste ausgibt. Ein Akkordeon-Element wird dann z.B. von einem <li>-Element umschlossen. So bekommen z.B. Benutzer von Screenreadern direkt einen Eindruck um wieviele Elemente es sich handelt. Dann macht es auch Sinn auf Überschriften der einzelnen Elemente zu verzichten. Eine grosse Anzahl Überschriften führt zu ähnlichen Problemen wie bei zu vielen Landmarks.
Progressive Enhancement
Es ist immer gut wenn Inhalte auch ohne JavaScript zugänglich sind. Das kann z.B. im Reader Mode von Browsern nützlich sein. Wobei Reader Modes sehr unterschiedlich implementiert sind.
Insofern ist es gute Praxis standardmäßig alle Inhalte anzuzeigen und diese dann per JavaScript zu verstecken und die entsprechenden Attribute wie aria-expanded zu setzen. So sind die Inhalte auch ohne JavaScript verfügbar. Leider kann dies zu Content Shifts führen, da die Akkordeon-Elemente nach dem Laden der Seite geschlossen werden.
Warum verwenden wir nicht einfach und ?
?
Mit den Elementen <details> und <summary> gibt es bereits eine native Möglichkeit Akkordions zu erstellen. Hier funktioniert sogar die browserinterne Suchfunktion automatisch. Leider sind diese Elemente in Browsern nicht konsistent umgesetzt. Wenn Konsistenz über Browser und Screen-Reader hinweg wichtig ist, ist es (noch) besser auf eine eigene Implementierung zurückzugreifen. Zudem gibt es Limitierungen bei der Gestaltung.
Das wird aber Thema eines eigenen Beitrags.