Barrierefreie Toggles: Was WCAG 2.2 wirklich verlangt

Ein Toggle sieht simpel aus — ist aber eine der am häufigsten falsch gebauten Komponenten. Ein hübscher Switch, den man nicht mit der Tastatur bedienen kann, ist für viele Menschen schlicht kaputt. So machst du es nach WCAG 2.2 richtig.
Baue auf nativem HTML auf
Der wichtigste Grundsatz: Nutze ein echtes <input type="checkbox"> oder einen <button>. Ein <div> mit Klick-Handler bekommst du niemals vollständig barrierefrei. Native Elemente bringen Fokus, Tastaturbedienung und den Zustand für assistive Technologie kostenlos mit.
Die WCAG-2.2-Checkliste
- Beschriftung: Jeder Toggle hat ein verknüpftes
<label>(2.5.3, 4.1.2). - Tastatur: mit
Taberreichbar, mitLeertasteumschaltbar (2.1.1). - Sichtbarer Fokus: ein deutlicher
:focus-visible-Ring (2.4.7, 2.4.11 in WCAG 2.2). - Zustand erkennbar: nicht nur über Farbe — Position/Form ändern sich (1.4.1).
- Zielgröße: mindestens 24×24 px, besser 44×44 px (2.5.8, neu in WCAG 2.2).
- Bewegung: Übergänge respektieren
prefers-reduced-motion(2.3.3).
Ein vollständig barrierefreier Toggle
Diese Variante nutzt eine echte Checkbox, verbirgt sie visuell (aber nicht für Screenreader) und stylt den sichtbaren Switch über das Geschwister-Element:
<label class="switch">
<input type="checkbox" checked>
<span class="track" aria-hidden="true"></span>
<span class="switch-label">Benachrichtigungen</span>
</label>
<style>
.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
/* Checkbox visuell verstecken, aber bedienbar & für SR sichtbar lassen */
.switch input {
position: absolute; opacity: 0; width: 0; height: 0;
}
.track {
width: 46px; height: 26px; border-radius: 99px;
background: #3a3a4a; position: relative;
transition: background .25s ease;
}
.track::after {
content: ""; position: absolute; top: 3px; left: 3px;
width: 20px; height: 20px; border-radius: 50%;
background: #fff; transition: transform .25s ease;
}
/* Zustand: an */
.switch input:checked + .track { background: #8b5cf6; }
.switch input:checked + .track::after { transform: translateX(20px); }
/* Sichtbarer Fokus für Tastatur */
.switch input:focus-visible + .track {
outline: 2px solid #8b5cf6; outline-offset: 2px;
}
/* Bewegung reduzieren */
@media (prefers-reduced-motion: reduce) {
.track, .track::after { transition: none; }
}
</style>Alternative: role="switch"
Wenn du statt einer Checkbox einen <button> nutzt, musst du den Zustand selbst über aria-checked und role="switch" abbilden — und das Umschalten per JavaScript übernehmen:
<button type="button" role="switch" aria-checked="true" class="switch-btn">
<span class="visually-hidden">Dunkelmodus</span>
</button>Häufige Fehler
- Zustand nur über Farbe (rot/grün) signalisieren — für Farbfehlsichtige nicht erkennbar.
- Fokus-Ring per
outline: noneentfernen, ohne Ersatz. - Zu kleine Klickfläche (unter 24 px) — verstößt gegen WCAG 2.2 (2.5.8).
- Kein Label — der Screenreader liest nur „Kontrollkästchen“ ohne Bedeutung vor.
Fazit
Barrierefreiheit beim Toggle ist kein Extra, sondern das Fundament. Baue auf nativem HTML, halte die Checkliste ein — dann funktioniert dein Switch für alle. Geprüfte Beispiele findest du in der Toggle-Sammlung.
Direkt loslegen
Durchstöbere passende Komponenten zum Kopieren.