Texte und HTML-Inhalte mit CSS und ARIA barrierefrei verstecken
Wenn Inhalte auf Webseiten versteckt werden, sollte Barrierearmut immer berücksichtigt werden. Wir zeigen unterschiedliche Lösungen für verschiedene Zwecke.
Es gibt zahlreiche Gründe, weshalb Inhalte auf einer Webseite versteckt werden sollen. Bei der handwerklich korrekten Umsetzung spielt Barrierefreiheit immer eine Rolle, denn neben dem vollständigen Verstecken von Inhalten für alle Personen können Elemente auch nur für sehende Menschen oder nur für assistive Technologien wie Screenreader versteckt werden. Wir geben einen Überblick wie Inhalte mit CSS im jeweiligen Anwendungsfall korrekt versteckt werden.
Beispiele für das Verstecken von Inhalten auf einer Website
Es gibt es drei zentrale Gründe aus denen Inhalte versteckt werden:
- Für alle Personen und Technologien sollen bestimmte Inhalte so lange versteckt sein, bis eine Bedingung erfüllt ist, in der Regel durch eine Aktion. Typische Beispiele sind:
- Accordions
- Modals (PopUps, Overlays)
- Tabs / Tabbed Content
- Für nicht-sehende Menschen sollen Inhalte wahrnehmbar sein, die für sehende Menschen nicht angezeigt werden. Ein Beispiel ist der sogenannte »Skip Link«, mit dem man bei Tastaturbenutzung vom Anfang der Seite zum anderen Bereichen der Seite springen kann, ohne jedes Mal die gesamte Navigation »durchzutabben«.
- Für nicht sehende Menschen und entsprechende Hilfstechnologien sollen Elemente verborgen werden, wohingegen sie für Sehende wahrnehmbar sind und einen Mehrwert bringen. Ein Beispiel sind grafische Icons, die einen Inhalt veranschaulichen, aber nicht ersetzen, wie etwa eine Grafik mit einem „X“ neben dem Wort »Schließen«.
Für jeden Einsatzzweck eignen sich verschiedene Möglichkeiten mehr oder weniger gut. Wir stellen euch diese im folgenden vor und erläutern kurz die Gründe dahinter.
Inhalte für alle Menschen und Technologien verstecken
Die folgenden Techniken werden eingesetzt, wenn Inhalte zeitweilig völlig versteckt werden sollen.
CSS-Deklaration display: none
Entfernt die Elemente vollständig aus dem DOM. Mit display: none;
ausgezeichnete Inhalte sind für keine Person zugänglich. Diese Methode ist dann am besten geeignet, wenn die Inhalte zugänglich sein sollen, falls CSS nicht greift. Es gibt allerdings immer wieder mal Diskussionen dazu in Hinblick auf SEO und Google.
HTML-Attribut hidden
Dieses Attribut ist in HTML5 hinzugekommen und bewirkt im Wesentlichen das gleiche wie display: none
. Um die Wirkung in älteren (Legacy) Browsern sicherzustellen, genügt das HTML-Attribut nicht (s. Browsersupport). Diese Methode kommt zum Einsatz, wenn die Inhalte auch ohne CSS nicht zugänglich sein sollen.
CSS-Deklaration visibility: hidden
Ebenso wie display: none
verbirgt visibility: hidden;
Inhalte völlig vor allen Personen, allerdings mit zwei wichtigen Unterschieden:
- Der Inhalt wird nicht aus dem normalen DOM-Flow entfernt, das Element behält seinen »physischen Platz« im Dokument.
- Diese Deklaration ermöglicht CSS-Transitions. Deshalb ist diese Umsetzung angebracht, wenn Inhalte mit einer Transition zwischen verstecktem und sichtbarem Zustand wechseln sollen.
Um Punkt 1 zu überwinden, kombinieren wir die Deklaration am besten mit anderen Eigenschaften wie position: absolute
, overflow: hidden
, height: 0
und dgl.
Sichtbarkeit nach Aktion barrierefrei herstellen
Die drei beschriebenen Techniken werden häufig verwendet um interaktive Komponenten (z. B. Accordions) herzustellen. Diese Komponenten haben verschiedene Zustände – also z. B. eingeklappt und ausgeklappt im Falle des Accordions. Mit Hilfe sog. ARIA-Attribute informieren wir nicht-sehende Menschen und Maschinen darüber, welchen Status die Komponente hat. Die Wahl des ARIA-Attributs ist abhängig von der Art der Komponente.
Beispiel: <div>
per <button>
ein- und ausblenden
Das folgende Beispiel zeigt einen versteckten <div>
, der per Klick auf einen <button>
ein- und ausgeblendet werden kann. Wir nutzen JavaScript, um Attribute oder Klassen auf den auslösenden Elementen zu tauschen.
Im HTML ist das ARIA-Attribut nicht vorhanden, erst wenn JavaScript ausgeführt werden kann, wird aria-expanded="false"
per JavaScript hinzugefügt, um bei Klick auf den Button auf aria-expanded="true"
zu wechseln. Damit stellen wir sicher, dass diese Inhalte auch bei nicht aktivem JavaScript verfügbar sind.
<button type="button">Inhalt zeigen</button>
<div class="hidden-complete">
<p>Dieser Inhalt ist initial vollständig verborgen.</p>
</div>
Per CSS verstecken wir den <div>
mit der Klasse .hidden-complete
. Der zweite CSS-Selector blendet den <div>
wieder ein, wenn das vorherige Element (der Button) das korrekte ARIA-Attribut per JavaScript erhalten hat
.hidden-complete {
display: none;
}
[aria-expanded="true"] + .hidden-complete {
display: block;
}
Mit Hilfe von JavaScript (hier jQuery) fügen wir dem <button>
-Element das ARIA-Attribut hinzu. Per Klick wechselt dieses zwischen den Zuständen true
und false
.
$('button').attr('aria-expanded', 'false');
$('button').on('click', function () {
var $this = $(this);
var $state = $this.attr('aria-expanded');
$this.attr('aria-expanded', $state === 'true' ? 'false' : 'true') }
);
Inhalte optisch verstecken aber für nicht sehende Menschen verfügbar machen
Es gibt mehrere Möglichkeiten, Inhalte vor sehenden Menschen zu verbergen. Der folgende Code deckt bereits viele Anwendungsfälle ab:
.hidden-visual:not(:focus):not(:active) {
position: absolute;
width: 1px;
height: 1px;
clip: rect(0 0 0 0);
clip-path: inset(50%);
overflow: hidden;
white-space: nowrap;
}
Hier tilgen diverse CSS-Deklarationen jede sichtbare Spur des Elements aus der normalen Abfolge im HTML-Dokument, dem sogenannten DOM-Flow.
Visuell verborgen, sichtbar beim :focus-Zustand
Durch die :not
-Teile des CSS-Selektors bleiben Elemente immer unsichtbar, die generell nicht fokussierbar sind. Das können unterstützende Hilfen sein wie etwa ergänzende Formular-Labels. Fokussierbare Elemente wie die bereits erwähnten »Skip Links« werden bei Fokus sichtbar.
Visuell verborgen, für Screenreader erfassbar
Um sicherzustellen, dass die Inhalte nur im beabsichtigten Kontext von Screenreadern erfasst werden, werden sie mit dem HTML-Attribut hidden
ausgezeichnet. Damit sie eindeutig zugeordnet werden, bekommen sie eine ID.
Das fokussierbare Element, zu dem diese Inhalte ausgegeben werden sollen, bekommt das ARIA-Attribut aria-describedby
, dem die oben vergebene ID zugeordnet wird.
Wenn der Screenreader dann die entsprechende Stelle im Markup erreicht, liest er den Beschreibungstext vor.
<p hidden id="beispiel">
Spezifische Erläuterungen, die nur für Screenreader beim Fokussieren eines Elements zugänglich sind.
</p>
<!-- ... -->
<button type="button" aria-describedby="beispiel">Hier klicken</button>
Neben aria-describedby
gibt es u.a. auch noch aria-labelledby
für einen Beschreibungstitel.
Inhalte für Screenreader verstecken und für sehende Menschen anzeigen
Elemente die ausschließlich dekorativen Zwecken dienen, sollten vor assistiven Technologien verborgen werden. Das betreffende Element wird mit dem ARIA-Attribut aria-hidden="true"
ausgezeichnet:
<button type="button">
<!-- Ausschließlich sichtbares Icon mit X-Symbol -->
<span class="icon-close" aria-hidden="true"></span>
<!-- Der folgende, nicht sichtbare Text für den Button -->
<span class="hidden-visual">Schließen</span>
</button>
Folgende Punkte sind beim Nutzen von aria-hidden
zu beachten:
- Das Attribut nicht bei fokussierbaren Elementen einsetzen: Diese sind immer noch fokussierbar, werden vom Screenreader aber nicht angekündigt. Das heißt
aria-hidden
ist nicht mit CSS überstimmbar (wiehidden
).- Wenn der Wert mit JavaScript getauscht werden soll, dann nicht
"true"
im HTML-Code schreiben. Ansonsten ist das Element nicht zugänglich, falls JavaScript nicht verfügbar ist.
Fazit
Wenn wir diese unterschiedlichen Techniken zweckdienlich und sorgsam einsetzen, können wir für jede Zielgruppe eine optimale User Experience schaffen. Die Möglichkeit, Inhalte zu verstecken, sollten wir aber nicht dazu gebrauchen, etwaige Schwachstellen im strukturellen und visuellen Design damit zu überdecken.
Unser Ziel sollte es immer sein, Nutzeroberflächen und -erlebnisse zu schaffen, die für so viele Benutzer wie möglich so zugänglich, verständlich und angenehm wie möglich sind.
Vielen Dank für den ausführlichen Blogeintrag! Da ich derzeit selbst an einer Webseite arbeite, würde ich gerne wissen, ob die Button-Funktion auch nur mit CSS umgesetzt werden kann. Der Hintergrund ist, dass ich gerne auf JavaScript verzichten würde und alle Style- bzw. Animationselemente lediglich über CSS realisieren möchte. Bisher konnte ich dafür aber keine Lösung finden.
Hallo Tim,
Style-Änderungen setzen wir ja auch bei den beschriebenen Methoden mit CSS um. Wofür wir JavaScript brauchen, ist das Ändern der Zustände mit ARIA-Attributen. Eine semantisch richtige und barrierefreie Umsetzung mit CSS ist uns nicht bekannt.
Eine reine CSS-Lösung wäre mittels versteckter radio-Buttons möglich. Das Markup bestünde dann z.B. für ein Accordion aus einer Reihe von lorem ipsumlorem ipsum dolor sit amet consectetuer adipiscing elit. im css würde dann mittels [type=“radio“]:checked + p oder ähnlich die max-height des p über eine transition zwischen 0 und Over9000 geändert. Die radio buttons selbst würden ausgeblendet. Durch tabindex=“-1″ werden sie auch nicht mehr von screenreadern beachtet soweit ich weiß.
Eine reine CSS-Lösung wäre mittels versteckter radio-Buttons möglich. Das Markup bestünde dann z.B. für ein Accordion aus einer Reihe von `lorem ipsumlorem ipsum dolor sit amet consectetuer adipiscing elit.` im css würde dann mittels `[type=“radio“]:checked + p` oder ähnlich die max-height des p über eine transition zwischen 0 und Over9000 geändert. Die radio buttons selbst würden ausgeblendet. Durch `tabindex=“-1″` werden sie auch nicht mehr von screenreadern beachtet soweit ich weiß.