skip to main content zum Hauptinhalt springen

accessible web-elements Barrierearme Web-Elemente

Möglichst ressourcenschonend und allem voran barrierearm zu entwickeln, ist mir ein großes Anliegen geworden. Das inklusive Entwickeln kann verwirrend sein durch unterschiedliche Standards und Screenreader.
Deshalb habe ich mich entschieden, ein paar der Elemente zu teilen, die mich selbst umgetrieben haben. Copy&paste erlaubt :)
Bei Anregungen und Fragen immer melden: kawabe-lux@posteo.de

Developing with as few resources as possible and, above all, with as few barriers as possible has become a major concern for me. Developing inclusively can be confusing due to different standards and screen readers.
That's why I decided to share some of the elements that have been driving me around. Copy&paste encouraged :)
For suggestions and questions always get in touch: kawabe-lux@posteo.de

Sprache umschalten language switch

open in github external link

Lowering the language barrier can be a good way to make content accessible to more readers. What is needed is a switch that can be used to change the language. It is even better if the switch directly uses the existing semantic possibilities offered by HTML and ARIA. Furthermore, the visual design should allow a clear assignment of the active state, i.e. the selected language.

A good solution for this is a pair of radio buttons that executes a short JavaScript code on each switch, which changes the lang attribute of the page root according to the language. The actual switching of the language for each element is handled by CSS rules.

in github öffnen externer Link

Die Senkung der Sprachbarriere kann ein guter Weg sein, um Inhalte für mehr Leser zugänglich zu machen. Nötig dafür: Ein Schalter, mit dem die Sprache umgeschaltet werden kann. Noch besser, wenn dabei der Schalter direkt die bereits vorhandenen semantischen Möglichkeiten ausnutzt, die HTML und ARIA einem bieten. Weiterhin sollte die visuelle Gestaltung eine eindeutige Zuordnung des aktiven Zustands, also der ausgewählten Sprache, ermöglichen.

Eine gute Lösung hierfür ist ein Paar von Radio-Buttons, der bei jedem Umschalten einen kurzen JavaScript-Code ausführt, der der Seitenwurzel das lang-Attribut entsprechend der Sprache verändert. Der eigentliche Wechsel der Sprache für jedes Element wird von CSS-Regeln übernommen.

First result. Open in CodePen external link
Erste Lösung. In CodePen öffnen externer Link

So far, so good. This solution is elegant in that much of the usability in the input elements is already provided by the browser. The use of the <fieldset> element with the <legend> element is semantic and solves all label accessibility needs.

However, if you want to design the fieldset differently and are dependent on a change to the display property (e. g. to flex or inline) for this, you come up against limitations on the part of the browsers. For example, Daniel Holbert, a developer at Mozilla, writes about a feature request for support of additional display values for buttons for Firefox:

„<button> is not implementable (by browsers) in pure CSS, so they are a bit of a black box, from the perspective of CSS. This means that they don't necessarily react in the same way that e.g. a <div> would. […] this isn't specific to <button>. Consider <fieldset> and <table> which also have special rendering behavior […]
In these cases, Chrome agrees with us and disregards the "flex" display mode.“

That was eight years ago and today, in 2021, nothing has changed in this respect at <fieldset> and probably won't change for the foreseeable future.

So if you want to do without further nesting in the HTML and rely on your own display values, then you have to replace these special elements with a more generic <div> with role="radiogroup". The label logic, which was previously inherently integrated by the <legend> element, must therefore be set with aria-labelledby.

So weit so gut. Diese Lösung ist insofern elegant, dass ein Großteil der Bedienbarkeit in den Input-Elementen bereits vom Browser bereitgestellt wird. Die Nutzung des <fieldset>-Elements mit <legend>-Element ist semantisch und löst alle Label-Bedüfnisse der Barrierefreiheit.

Wenn man jedoch das Fieldset anders gestalten möchte und dafür auf eine Änderung der display-Eigenschaft (z. B. auf flex oder inline) angewiesen ist, stößt man auf Grenzen seitens der Browser. Beispielsweise schreibt Daniel Holbert, Entwickler bei Mozilla, zu einem Featureantrag für die Unterstützung von weiteren display-Werten bei Buttons für Firefox:

„<button> is not implementable (by browsers) in pure CSS, so they are a bit of a black box, from the perspective of CSS. This means that they don't necessarily react in the same way that e.g. a <div> would. […] this isn't specific to <button>. Consider <fieldset> and <table> which also have special rendering behavior […]
In these cases, Chrome agrees with us and disregards the "flex" display mode.“
(aus [1])

„<button> kann (von den Browsern) nicht in reinem CSS implementiert werden, so dass sie aus der Sicht von CSS eine Art Blackbox sind. Das bedeutet, dass sie nicht unbedingt auf die gleiche Weise reagieren wie z. B. ein <div>. […] dies ist nicht spezifisch für <button>. Siehe <fieldset> und <table>, die ebenfalls ein spezielles Rendering-Verhalten haben […]
In diesen Fällen stimmt Chrome mit uns überein und ignoriert die Display-Eigenschaft ‚flex‘.“ (eigene Übersetzung)

Das ist acht Jahre her und heute, 2021, hat sich in dieser Hinsicht bei <fieldset> noch nichts geändert und wird sich wahrscheinlich auf absehbarer Zeit nicht ändern.

Wenn man also auf weitere Verschachtelung im HTML verzichten möchte und auf eigene display-Werte setzt, dann muss man diese speziellen Elemente durch ein generischeres <div> mit role="radiogroup" ersetzen. Die Label-Logik, die vorher durch das <legend>-Element von Haus aus integriert war, muss daher mit aria-labelledby gesetzt werden.


          
          
HTML markup of the new switch element without fieldset. HTML-Markup des neuen Switch-Elements ohne fieldset.

So far, so good. This solution can be extended and optimized almost infinitely. The functions that seem to me to be important besides the mere language switching are

  • activation of the element only with JavaScript support,
  • saving the language selection between pages and
  • loading the saved setting.

Diese Lösung kann fast endlos erweitert und optimiert werden. Die Funktionen, die mir neben der reinen Sprachumschaltung noch wichtig erscheinen umgesetzt zu werden, sind

  • Einschalten des Elements erst bei JavaScript-Unterstützung,
  • Speicherung der Sprachauswahl zwischen den Seiten und
  • Laden der gespeicherten Einstellung.
Extended result. Open in CodePen external link
Erweiterte Lösung. In CodePen öffnen externer Link

The element is disabled by default with help of the CSS class js-only. The JavaScript function enableJsOnly adds a new style element to the head that shows the hidden class again.

The function setSwitch(name, callback) can be used for the creation of other dual switches as well (see next snippet).

Das Element ist standardmäßig mithilfe der CSS-Klasse js-only deaktiviert. Die JavaScript-Funktion enableJSOnly fügt ein neues Style-Element dem Head hinzu, das die deaktivierte Klasse wieder aktiviert.

Die Funktion setSwitch(name, callback) kann dabei auch für die Erstellung anderer dualer Schalter verwendet werden (siehe nächstes Snippet).

theme switch Ansicht umschalten

open in github external link

Another way to make content accessible to more people is a changeable color scheme. People with different vision have different needs and tastes when it comes to choosing a rather light or rather dark design of texts (see e.g. [1]). This can be derived from the browser setting and can be toggled as needed using a switch like the previous snippet.

The most important technology here is the CSS rule @media only screen and (prefers-color-scheme:dark) (see CSS). It allows to create rules that take effect only if the browser uses a dark scheme.

The main differences between light and dark color schemes are in the colors used. In order not to have to create two completely different designs of the website, CSS variables can be used for all colors, so that only the variables have to be changed when changing the scheme. This can basically be done in the same way for images: Instead of using the URL, use URL variables that are changed when the scheme changes.

Three rules are eventually needed in the stylesheet:

  1. default color scheme (e.g. light)
  2. optional color scheme selected by the browser (e.g. dark)
  3. optional color scheme selected by the user (e.g. dark)

2. and 3. unfortunately cannot be merged, because a media query is not a selector and thus cannot be added to a rule case with other selector rules.

in github öffnen externer Link

Ein weiterer Weg, um Inhalte für mehr Meschen zugänglich zu machen, ist ein veränderbares Farbschema. Unterschiedlich sehende Menschen haben unterschiedliche Bedürfnisse und Geschmäcker bei der Wahl einer eher hellen oder eher dunklen Gestaltung von Texten (siehe z. B. [1] (auf Englisch)). Dies kann von der Browser-Einstellung abgeleitet werden und bei Bedarf mithilfe eines Schalters wie beim vorherigen Snippet umgeschaltet werden.

Die wichtigste Technologie hierbei ist die CSS-Regel @media only screen and (prefers-color-scheme:dark) (siehe CSS). Sie ermöglicht, Regeln zu erstellen, die nur greifen, falls der Browser ein dunkles Schema verwendet.

Die wichtigsten Unterschiede zwischen hellem und dunklem Farbschema liegen in den verwendeten Farben. Um nicht zwei gänzlich unterschiedliche Gestaltungen der Webseite erstellen zu müssen, können für sämtliche Farben CSS-Variablen verwendet werden, sodass bei Schemaänderung nur die Variablen verändert werden müssen. Dies kann im Grunde genauso für Bilder gemacht werden: Statt die URL zu verwenden, verwendet man URL-Variablen, die bei Schemaänderung geändert werden.

Im Stylesheet werden letztendlich drei Regeln gebraucht:

  1. Standardfarbschema (z. B. hell)
  2. vom Browser ausgewähltes optionales Farbschema (z. B. dunkel)
  3. von Nutzenden ausgewähltes optionales Farbschema (z. B. dunkel)

2. und 3. können leider nicht zusammengeführt werden, da eine Media-Query kein Selektor ist und damit nicht mit anderen Selektorenregeln zu einem Regelfall addiert werden kann.

Theme switch for dark and light mode. Open in CodePen external link
Ansichtschalter für dunklen und hellen Modus. In CodePen öffnen externer Link

The other features of this snippet are, similar to the language switch,

  • Turning on the element only when JavaScript is supported,
  • saving the scheme selection between pages and
  • Loading the saved setting.

By the way: On this page and in the snippet, a light standard color scheme is assumed, since this is considered to be the easiest to read for most people in the current state of research (2021). However, one could argue for using dark default color schemes to reduce the power consumption of the end devices due to the more widespread use of OLED screens (see [2]).

Die weiteren Features dieses Snippets sind, ähnlich wie beim Sprachumschalter,

  • Einschalten des Elements erst bei JavaScript-Unterstützung,
  • Speicherung der Schemaauswahl zwischen den Seiten und
  • Laden der gespeicherten Einstellung.

Übrigens: Auf dieser Seite und in dem Snippet wird von einem hellen Standardfarbschema ausgegangen, da dies im jetzigen Stand der Forschung (2021) als am leichtesten lesbar für die meisten Menschen gilt. Man könnte jedoch aufgrund der stärkeren Verbreitung von OLED-Bildschirmen (siehe [2]) dafür plädieren, dunkle Standardfarbschemata zu verwenden, um den Stromverbrauch der Endgeräte zu verringern.