Barrierefreies Webdesign ein zugängliches und nutzbares Internet gestalten

Inhalte mit CSS? Aber bitte ohne Hintergrundgrafiken! veröffentlicht in 2012

Generierte Inhalte mit content

Mit der CSS-Eigenschaft Extern: content in Verbindung mit den Pseudo-Attributen :before und :after können Inhalte vor oder hinter HTML-Elemente eingefügt werden. Wie Intern: CSS-Aufzählungszeichen werden Inhalte, die mit der CSS-Eigenschaft content eingefügt werden, im Kontrastmodus des Browsers beibehalten.

Wenn zum Beispiel CSS Sprites eingesetzt werden, um eine Werkzeugleiste darzustellen, dann können sie auch mit CSS barrierefrei umgesetzt werden, vorausgesetzt die Grafik wird nicht als Intern: Hintergrundgrafik eingebunden.

Acht Symbole in einer Grafik Vier Symbole für eine Werkzeugleiste und vier weitere für einen Fokus- und Mouse-Over-Effekt

CSS Sprites sind eine Technik, bei der mehrere kleine Grafiken in eine Grafik zusammengefasst werden und dabei immer nur ein Teil der Grafik mittels CSS angezeigt wird. So können zum Beispiel alle auf einer Webseite verwendeten Symbole in einer Grafikdatei abgebildet werden; jedes Mal, wenn ein Symbol am Bildschirm angezeigt werden soll, wird die gleiche Datei eingebunden, nur wird immer nur ein Ausschnitt der Grafik am Bildschirm sichtbar gemacht. Ein Vorteil dieser Technik ist, dass die Grafik nur einmal geladen werden muss und somit die Seite insgesamt schneller laden kann. Auch bei dynamischen Effekten, etwa der Austausch der Grafik bei Mouse-Over und Fokus, muss lediglich der angezeigte Ausschnitt per CSS geändert werden, anstatt eine neue Grafik zu laden.

Eine zweite Voraussetzung für die Barrierefreiheit von CSS Sprites ist eine Intern: Textangabe im HTML für das Steuerelement. Der Inhalt, der mit content dargestellt wird, wird zwar am Bildschirm angezeigt, taucht aber nicht im DOM auf, kann kein Alternativtext erhalten und kann daher Extern, englischsprachig: von Screenreadern nicht erfasst werden (Hinweis: Es gibt Extern, englischsprachig: Ausnahmen und in bestimmten Situationen werden mit content eingefügte Inhalte von Screenreadern doch gelesen. Bei Grafiken ist das allerdings nicht der Fall).

Bei Schaltflächen kann ein Text im BUTTON-Element berücksichtigt werden. Bei Links muss ebenfalls die Funktion im Linktext aufgenommen werden.

Beispiel mit BUTTON

Das HTML für eine Werkzeugleiste könnte wie folgt aussehen:

<div id="schalter">
  <button type="button" class="speichern">Speichern</button>
  <button type="button" class="drucken">Drucken</button>
  <button type="button" class="info">Info</button>
  <button type="button" class="abbrechen">Abbrechen</button>
</div>

Der Text innerhalb des BUTTON-Elements gibt den Schaltflächen einen Namen, wodurch sie auch von Screenreadern gelesen werden können. Im Folgenden wird die Sichtbarkeit der Symbole im Kontrastmodus des Browsers mit Hilfe von content vorgestellt.

Die Schaltflächen sollen am Bildschirm mit CSS Sprites dargestellt werden. Zunächst sollten die BUTTON-Elemente eine konkrete Breite und Höhe erhalten und die Eigenschaft overflow auf hidden gesetzt werden:

#schalter button {
  width: 48px;
  height: 48px;
  overflow: hidden;
  border: 1px solid #000;
  padding: 0px;
  margin: 5px;
  vertical-align: top ; /* für FF */
}

Nachdem die Darstellungsfläche festgelegt ist, kann mit content im Zusammenspiel mit den Pseudo-Attribut :before die Grafik für jede Schaltfläche eingebunden werden:

#schalter button:before {
  display: inline-block;
  padding: 0px;
  content: url('icons.png');
}

Jetzt muss für jede einzelne Schaltfläche die CSS-Grafik passend positioniert werden:

#schalter .speichern:before {
  margin-top: -147px;
}
#schalter .drucken:before {
  margin-top: -98px;
}
#schalter .info:before {
  margin-top: -49px;
}
#schalter .abbrechen:before {
  margin-top: 1px;
}

Mit diesen Anweisungen wird die Grafik für jede Schaltfläche so positioniert, dass das entsprechende Symbol aus der Grafik genau in den vorgegebenen Platz passt. Weil die Grafik sich am Anfang des Textknotens "hineindrängt", wird der jeweilige Schaltflächentext nach rechts außerhalb des sichtbaren Bereichs der Schaltfläche geschoben. Der Text bleibt dabei für Screenreader zugänglich.

Bei der Verwendung von background statt content kann im Übrigen ebenfalls ein Text für Screenreader berücksichtigt werden (der Text innerhalb von BUTTON wird beispielsweise Intern: mit position:absolute; außerhalb des sichtbaren Bereichs der Schaltfläche geschoben). Die Verwendung von content statt background hebt aber das Problem von unsichtbaren Schaltflächen im Kontrastmodus auf:

Zwei Darstellungen der Werkzeugleiste: in Standardfarben und im Kontrastmodus Im Kontrastmodus funktioniert content, background aber nicht

Schaltflächen mit dem BUTTON-Element sind hinsichtlich der Gestaltung mit CSS etwas wackelig und immer für eine Überraschung gut, und das Beispiel stellt zunächst lediglich ein Grundgerüst dar. Für Firefox muss noch ein Problem mit dem Fokus behoben werden. Die Technik funktioniert außerdem im Internet Explorer wegen der content-Eigenschaft erst ab Version 8. Für Versionen 6 und 7 muss JavaScript zum Einsatz kommen (folgt weiter unten auf dieser Seite).

Beispiel mit INPUT

Alternativ zu BUTTON kann auch INPUT eingesetzt werden. Die Screenreaderfähigkeit wird im Folgenden mit dem alt-Attribut erreicht:

<p class="speichern"><input type="image" src="icons.png" alt="Speichern" /></p>

Mit INPUT wird die Grafik auf die HTML-Ebene zurückverlagert, d.h. die Grafik wird im Kontrastmodus angezeigt. Auch für Grafiken im HTML können CSS Sprites eingesetzt werden:

.speichern {
  width: 48px;
  height: 48px;
  overflow: hidden;
  border: 1px solid #000;
  padding: 0;
  margin: 5px;
}
.speichern input {
  margin-top: -147px;
}

Nachteilig bei CSS Sprites in Verbindung mit Grafiken auf der HTML-Ebene ist, dass bei ausgeschaltetem CSS die komplette Grafik angezeigt wird. D.h. die Technik mit BUTTON ist vorzuziehen, weil dann der Text der Schaltfläche als Fallback angezeigt wird.

Beispiel für Links

Analog zu Schaltflächen können natürlich auch Links eingesetzt werden, um anklickbare Symbole am Bildschirm anzuzeigen. Auch bei Links dürfen keine Hintergrundgrafiken verwendet werden, wenn die Grafiken informativ sind. Das Beispiel für die CSS Sprites in Schaltflächen wird analog aufgebaut:

<div id="links">
  <a href="#" class="speichern">Speichern</a>
  <a href="#" class="drucken">Drucken</a>
  <a href="#" class="info">Info</a>
  <a href="#" class="abbrechen">Abbrechen</a>
</div>

Wichtig ist auch hier, dass der Linktext vorhanden ist. Das CSS muss leicht angepasst werden, um das gleiche Ergebnis am Bildschirm zu erzielen wie im ersten Beispiel:

#links a {
  width: 48px;
  height: 48px;
  overflow: hidden;
  display:block;
  float:left;
  border: 1px solid #000;
  padding: 0;
  margin: 5px;
}
#links a:before {
  display: inline-block;
  content: url('icons.png');
}
#links .speichern:before {
  margin-top: -147px;
}
#links .drucken:before {
  margin-top: -98px;
}
#links .info:before {
  margin-top: -49px;
}
#links .abbrechen:before {
  margin-top: 1px;
}

Internet Explorer 6 und 7

Etwas aufwendiger ist die Umsetzung von CSS Sprites mit content in Internet Explorer 6 und 7. Da content in diesen Browsern nicht unterstützt wird, muss als Fallbacklösung die Wahl zwischen Pest und Cholera getroffen werden: Hintergrundgrafiken, die nicht barrierefrei sind, oder JavaScript, der möglicherweise im Browser des Nutzers abgeschaltet ist. In jedem Fall müssen einige Punkte beachtet werden.

Für eine barrierefreie Lösung eines CSS-Sprites mit BUTTON (siehe oben auf dieser Seite) sind für Internet Explorer 6 und 7 einige JavaScript-Anweisungen erforderlich. Darüber hinaus muss das CSS leicht angepasst werden. Um diese Anweisungen nur für diese Browserversionen einzubinden, kann auf Conditional Comments gesetzt werden:

<!--[if (IE 6)|(IE 7)]>
  ... was auch immer hier steht, es kriegen nur Internet Explorer 6 und 7 mit ...
<![endif]-->

Und darin neben den angepassten CSS-Deklarationen auch die erforderlichen JavaScript-Anweisungen hineinzupacken.

Mit JavaScript muss die Grafik in das BUTTON-Element hineingeschrieben werden:

<!--[if (IE 6)|(IE 7)]>
<script type="text/javascript">
  var schalter = document.getElementById ('schalter');
  var links = schalter.getElementsByTagName('button');
  for (i=0; i < links.length; i++) {
    links[i].insertAdjacentHTML("afterBegin", '<img id="button-'+i+'" src="icons.png" alt="" />');
  }
</script>
<![endif]-->

Im Quellcode müssen die JavaScript-Anweisungen den Schaltflächen folgen. Das CSS gehört hingegen im Kopfbereich der Seite:

<!--[if (IE 6)|(IE 7)]>
<style>
.speichern img {
  margin-top: -147px;
}
.drucken img {
  margin-top: -98px;
}
.info img {
  margin-top: -49px;
}
.abbrechen img {
  margin-top: 0px;
}
</style>
<![endif]-->

Mit etwas Aufwand kann also ein gewisses Maß an Rückwärtskomatibilität erzielt werden.

Ergebnis

Mit der CSS-Eigenschaft content können Symbole nur dann für alle zugänglich in Webseiten eingebunden werden, wenn die Rückwärtskompatibilität kein Thema ist.

Ob CSS Sprites eine gute Technik zur Einbindung von Symbolen ist, mag ich nicht beurteilen. Als Argument dafür wird meist die Performance angeführt.

Die Beispiele können heruntergeladen werden:

Anmerkung: Es sollte noch die Intern: Fokus-Problematik in verschiedenen Browsern berücksichtigt werden.