CSS: Zugänglichkeit
Fokus-Stile: outline und :focus-visible
Der Tastaturfokus wird mit outline gestaltet und mit :focus-visible gezielt dann angezeigt, wenn er gebraucht wird: outline zeichnet einen Rahmen, ohne das Layout zu verschieben, und :focus-visible greift bei Tastaturbedienung, während der reine Mausklick ohne Ring bleibt.
Die Pseudoklasse :focus-visible ist seit März 2022 in allen großen Browsern verfügbar und hat den ältesten Konflikt der Fokus-Gestaltung aufgelöst. Designer wollten den Ring beim Mausklick loswerden, Tastaturnutzende brauchen ihn zwingend. Seither gibt es keinen Grund mehr, outline: none ohne Ersatz zu schreiben.
Diese Seite ist die Referenz für die Gestaltung: die Eigenschaft outline mit ihren Teilwerten, die drei Fokus-Pseudoklassen im Vergleich und die Rezepte für Ringe, die auf jedem Hintergrund und im Windows-Kontrastmodus funktionieren.
Das Wichtigste in Kürze
-
outlinezeichnet den Fokusring außerhalb der Box und beansprucht keinen Platz. Beim Erscheinen verschiebt sich nichts. Das unterscheidet sie vonborder. -
:focustrifft jede Fokussierung,:focus-visiblenur die, die eine Anzeige braucht. Tastatur löst den Ring aus, der Mausklick auf einen Button löst ihn nicht aus. - Eingabefelder zeigen den Ring immer. Bei
inputundtextareagreift:focus-visibleauch nach einem Mausklick, weil dort jede Eingabe über die Tastatur läuft. -
:focus-withingestaltet das Elternelement, sobald ein Kind den Fokus hat. Das hebt Formulargruppen hervor und hält aufgeklappte Menüs für die Tastatur offen. -
box-shadowallein ist kein verlässlicher Fokusring. Der Windows-Kontrastmodus entfernt Schatten. Eine zusätzliche transparenteoutlinebleibt dort sichtbar. - Der Ring braucht mindestens 3:1 Kontrast zu den angrenzenden Farben. Das verlangt WCAG 1.4.11 auf Stufe AA. Die AAA-Zielmarke 2.4.13 ergänzt 2 Pixel Mindeststärke.
Abgrenzung: Diese Seite behandelt die Gestaltung des Fokus mit CSS. Was die Norm verlangt, wie du eine Seite per Tab-Runde prüfst und wie Fokus-Management mit tabindex, Dialogen und Skip-Links funktioniert, steht unter Tastaturbedienung und sichtbarer Fokus. Die normative Grundlage ist WCAG 2.4.7 Fokus sichtbar.
CSS outline: der Rahmen ohne Platzanspruch
outline ist die Kurzform aus outline-width, outline-style und outline-color und funktioniert wie border mit drei Unterschieden. Die Linie liegt außerhalb der Border-Box, sie zählt im Box-Modell nicht mit, und sie umschließt das Element immer an allen vier Seiten. Eine outline-bottom gibt es nicht.
button:focus-visible {
outline: 3px solid #0b3d91; /* Breite, Stil, Farbe */
outline-offset: 2px; /* Abstand zwischen Box und Ring */
}
outline-offset schiebt den Ring vom Element weg. Zwei Pixel Abstand machen ihn auf farbigen Buttons deutlich sichtbarer, weil zwischen Button und Ring die Hintergrundfarbe durchscheint. Negative Werte ziehen den Ring in das Element hinein. Das ist der Weg für Bilder oder Karten, deren Ring innerhalb der Kante liegen soll.
Stand September 2026 folgt outline in allen aktuellen Browsern dem border-radius des Elements. Runde Buttons bekommen runde Ringe, und der alte Grund für box-shadow als Ersatz ist damit weggefallen.
Ohne eigene Angabe zeigen Browser den Standardring des Betriebssystems. Chrome zeichnet zwei Pixel in einem kräftigen Blau, Firefox und Safari ähnlich. Dieser Standard erfüllt die Norm. Wer ihn ersetzt, übernimmt die Verantwortung dafür, dass der Ersatz sichtbarer ist und nie unsichtbar.
outline, border und box-shadow im Vergleich
| Eigenschaft | Platz im Layout | Folgt border-radius | Übersteht den Kontrastmodus |
|---|---|---|---|
outline |
beansprucht keinen | ja | ja, in Systemfarbe |
border |
zählt zur Box und verschiebt Nachbarn | ja | ja |
box-shadow |
beansprucht keinen | ja | wird entfernt |
border scheidet für Fokuszustände in der Praxis aus, weil das Erscheinen der Linie das Element vergrößert und das Layout springen lässt. Der Ausweg über eine dauerhaft transparente border funktioniert und kostet dafür an jedem Element Platz. outline erreicht dasselbe ohne Nebenwirkung.
:focus, :focus-visible und :focus-within im Vergleich
Die drei Pseudoklassen beantworten drei verschiedene Fragen. Hat das Element den Fokus? Soll der Fokus angezeigt werden? Hat ein Kind des Elements den Fokus?
:focus: jede Fokussierung
:focus trifft das Element bei jeder Art der Fokussierung: Tabulatortaste, Mausklick, Antippen, element.focus() per Skript. Für sich allein erzeugt das den Effekt, den Designer seit Jahren stört. Nach jedem Klick auf einen Button leuchtet der Ring, obwohl die Maus die Position bereits zeigt.
:focus-visible: die Anzeige-Heuristik des Browsers
:focus-visible überlässt dem Browser die Entscheidung, ob eine sichtbare Anzeige nötig ist. Die Heuristik ist in der Spezifikation bewusst offen formuliert, in der Praxis verhalten sich alle Browser gleich:
- Fokus per Tastatur aktiviert die Anzeige. Wer mit Tab auf einen Button springt, sieht den Ring.
- Fokus per Mausklick oder Touch auf Buttons und Links aktiviert sie nicht.
- Text-Eingabefelder zeigen die Anzeige immer, auch nach einem Mausklick. Der Browser geht davon aus, dass als Nächstes die Tastatur benutzt wird.
- Fokus per Skript übernimmt den Zustand der letzten Eingabe. Kam der Auslöser von der Tastatur, erscheint der Ring.
Das Grundmuster besteht aus zwei Regeln. Die erste gestaltet den sichtbaren Fall, die zweite räumt den Maus-Fokus ab, ohne Tastaturnutzenden etwas zu nehmen:
:focus-visible {
outline: 3px solid #0b3d91;
outline-offset: 2px;
}
/* Nur für den Fall, dass eigene :focus-Stile im Projekt existieren */
:focus:not(:focus-visible) {
outline: none;
}
Die zweite Regel ist das einzige outline: none, das eine Seite enthalten sollte, denn sie entfernt den Ring genau dort, wo :focus-visible ihn ohnehin nie zeigen würde. Warum eine zu breit geschriebene Regel mit höherer Spezifität den eigenen Ring wieder aushebelt, steht unter CSS-Selektoren und Spezifität.
:focus-within: das Elternelement reagiert
:focus-within trifft ein Element, sobald es selbst oder eines seiner Kinder den Fokus hat. Damit bekommen zusammengehörige Gruppen eine gemeinsame Hervorhebung:
/* Die ganze Formulargruppe hebt sich ab, sobald ein Feld aktiv ist */
.formular-gruppe:focus-within {
background: #eef4ff;
outline: 2px solid #0b3d91;
outline-offset: 4px;
}
/* Das Untermenü bleibt offen, solange die Tastatur darin steht */
.nav-item:focus-within > .untermenue {
display: block;
}
Das zweite Beispiel ist der Grund, warum :focus-within in jeder Navigation mit Untermenüs stehen sollte. Ein Menü, das nur auf :hover öffnet, schließt sich vor Tastaturnutzenden. Wie das vollständige Muster aussieht, zeigt die Seite zu Mega-Menüs.
:has(:focus-visible): die fehlende Kombination nachbauen
Eine Pseudoklasse :focus-visible-within existiert nicht. Seit alle Browser :has() unterstützen, lässt sie sich kombinieren. Die Gruppe reagiert dann nur auf Tastatur-Fokus und bleibt beim Mausklick ruhig:
.karte:has(:focus-visible) {
outline: 3px solid #0b3d91;
outline-offset: 2px;
}
Das passt zu klickbaren Cards, bei denen der Link im Inneren liegt und die ganze Karte als fokussiert erscheinen soll.
Ein Ring, der auf jedem Hintergrund funktioniert
Eine einzelne Ringfarbe scheitert, sobald die Seite helle und dunkle Flächen mischt. Ein dunkelblauer Ring verschwindet auf dem dunkelblauen Header, ein weißer auf der weißen Fläche. Drei Wege lösen das.
Der Doppelring kombiniert eine dunkle outline mit einem hellen Zwischenring aus box-shadow. Eine Farbe hebt sich immer ab. Das Rezept samt Kontrastrechnung steht im Abschnitt zum Fokusring unter Tastaturbedienung und sichtbarer Fokus.
currentColor übernimmt die Textfarbe des Elements als Ringfarbe. Für Links im Fließtext ist das die kürzeste Lösung, denn die Textfarbe muss ihren Kontrast zum Hintergrund bereits erfüllen:
a:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
}
Auf Buttons versagt der Ansatz, weil die Textfarbe dort meist der Flächenfarbe der Umgebung entspricht. Ein weißer Ring um einen blauen Button liegt auf weißem Seitengrund.
Zwei getrennte Regeln je Fläche bleiben der Ausweg, wenn ein Design dunkle und helle Bereiche strikt trennt: eine Ringfarbe für .dark-Container, eine für den Rest. Das kostet Pflege und ist der Grund, warum der Doppelring in gemischten Layouts die robustere Wahl ist. Welche Farbkombinationen 3:1 erreichen, prüft der Kontrast-Check.
Der Windows-Kontrastmodus: outline überlebt, box-shadow verschwindet
Im Forced-Colors-Modus ersetzt Windows alle Farben durch die Systempalette und entfernt jeden box-shadow. Ein Fokusring, der allein aus einem Schatten besteht, existiert dort nicht mehr. Genau dieser Modus wird von Menschen mit Sehbehinderung eingesetzt, die auf den Ring am stärksten angewiesen sind.
Die Lösung ist eine transparente outline zusätzlich zum Schatten. Im normalen Modus bleibt sie unsichtbar, im Kontrastmodus färbt das System sie mit der Systemfarbe ein:
.chip:focus-visible {
box-shadow: 0 0 0 3px #0b3d91;
outline: 3px solid transparent; /* erscheint nur im Kontrastmodus */
outline-offset: 1px;
}
Wer den Ring im Kontrastmodus gezielt gestalten will, nutzt die Systemfarbe Highlight in einer eigenen Media Query:
@media (forced-colors: active) {
.chip:focus-visible {
outline-color: Highlight;
}
}
Die Abfrage forced-colors gehört zur selben Familie wie prefers-reduced-motion und prefers-color-scheme. Die Übersicht dieser Systemabfragen steht unter Media Queries.
Fokus nicht verdeckt und nicht abgeschnitten
Ein sichtbarer Ring nützt nichts, wenn das fokussierte Element hinter einem klebenden Header liegt. WCAG 2.4.11 Fokus nicht verdeckt verlangt auf Stufe AA, dass das fokussierte Element mindestens teilweise sichtbar bleibt. Zwei Eigenschaften lösen das im CSS:
/* Am Dokument: reserviert beim Springen Platz für den 5rem hohen Header */
html { scroll-padding-top: 5rem; }
/* Oder am einzelnen Element: hält beim Fokussieren Abstand nach oben */
.sprungziel { scroll-margin-top: 5rem; }
scroll-padding gehört an den Scroll-Container und wirkt für alle Sprünge darin. scroll-margin gehört an das Zielelement und wirkt nur für dieses. Für einen Header, der auf jeder Seite klebt, ist scroll-padding-top am html-Element die eine Zeile, die das Problem seitenweit beseitigt.
Der zweite Verdeckungsfall ist der abgeschnittene Ring: Ein Vorfahre mit overflow: hidden kappt die outline an der Containerkante. Warum das passiert und wie overflow-clip-margin den Ring stehen lässt, steht unter CSS overflow.
Barrierefreiheit: worauf es ankommt
Vier Kriterien regeln den Fokus, zwei davon auf Stufe AA und damit im Pflichtbereich von BFSG und BITV:
- 2.4.7 Fokus sichtbar (AA): Bei Tastaturbedienung muss eine sichtbare Fokusanzeige existieren.
outline: noneohne Ersatz verstößt dagegen. - 1.4.11 Nicht-Text-Kontrast (AA): Der Ring braucht mindestens 3:1 Kontrast zu den angrenzenden Farben.
- 2.4.11 Fokus nicht verdeckt (AA): Sticky-Header und Cookie-Banner dürfen das fokussierte Element höchstens teilweise überlagern.
- 2.4.13 Fokus-Erscheinungsbild (AAA): mindestens 2 CSS-Pixel Stärke und 3:1 Kontrast zwischen fokussiertem und unfokussiertem Zustand. Die Stufe ist freiwillig. Als Gestaltungsrichtschnur taugt sie für jedes Projekt, und ein 3-Pixel-Ring mit
outline-offseterfüllt sie nebenbei.
So testest du den Fokusring
- Tab-Runde: Lade die Seite, lege die Maus weg und gehe mit der Tabulatortaste durch alle Bedienelemente. An jeder Position muss auf einen Blick erkennbar sein, wo der Fokus steht.
- Kontrast messen: Prüfe die Ringfarbe gegen die angrenzenden Flächen im Kontrast-Check. Die Zielmarke ist 3:1.
- Kontrastmodus emulieren: In den Chrome-DevTools unter „Rendering“ die Option „Emulate CSS media feature forced-colors“ aktivieren und die Tab-Runde wiederholen. Jeder Ring aus reinem
box-shadowfällt hier auf. - Zoom: Bei 200 Prozent Zoom die Runde wiederholen. Ein Ring, der jetzt hinter dem Sticky-Header oder an einer
overflow-Kante verschwindet, verletzt 2.4.11.
Häufiger Fehler in der Praxis
Das hartnäckigste Muster stammt aus CSS-Resets. Der meistkopierte Reset des Webs, der Meyer-Reset von 2008, enthielt die Zeile :focus { outline: 0; } samt dem Kommentar, Fokus-Stile bitte selbst zu definieren. Kopiert wurde die Zeile, der Kommentar nicht. In Audits zeigt sich das bis heute: Die Seite hat ein durchdachtes Design und beim Durchtabben ist der Fokus an keiner Stelle zu sehen, weil Zeile eins eines fünfzehn Jahre alten Resets ihn projektweit entfernt.
Die Prüfung dauert eine Minute. Im Stylesheet nach outline suchen und jeden Treffer mit none oder 0 daraufhin ansehen, ob in derselben Regel oder einer :focus-visible-Regel ein Ersatz steht. Ich empfehle, den Ring global auf :focus-visible zu definieren statt je Komponente. Ein Ring pro Seite ist konsistent, auffindbar und geht bei der nächsten Komponente nicht verloren.
Häufige Fragen
Warum sehe ich den Fokusring beim Klicken mit der Maus nicht?
Der Ring ist mit :focus-visible definiert, und diese Pseudoklasse greift beim Mausklick auf Buttons und Links absichtlich nicht. Der Browser zeigt die Anzeige nur, wenn sie zur Orientierung nötig ist, also bei Tastaturbedienung und in Eingabefeldern. Das ist das gewünschte Verhalten und kein Fehler. Mit der Tabulatortaste erscheint der Ring sofort.
Wie bekommt der Fokusring abgerundete Ecken?
Der Ring übernimmt die Rundung von selbst. Stand September 2026 folgt outline in allen aktuellen Browsern dem border-radius des Elements. Ein runder Button bekommt einen runden Ring, ohne zusätzlichen Code. Der früher übliche Umweg über box-shadow ist damit überflüssig und wegen des Windows-Kontrastmodus die schlechtere Wahl.
Welchen Kontrast braucht ein Fokusring?
Mindestens 3:1 gegenüber den angrenzenden Farben, so verlangt es WCAG 1.4.11 auf Stufe AA. Die AAA-Stufe 2.4.13 ergänzt 3:1 zwischen dem fokussierten und dem unfokussierten Zustand sowie eine Mindeststärke von 2 CSS-Pixeln. Ein 3 Pixel starker Ring in einer dunklen Farbe mit 2 Pixeln outline-offset erfüllt auf hellem Grund beide Stufen.
Ist box-shadow als Fokusring erlaubt?
Erlaubt ist er, verlässlich allein ist er nicht. Der Windows-Kontrastmodus entfernt alle Schatten, und der Ring verschwindet genau bei den Menschen, die ihn am dringendsten brauchen. Wer box-shadow für die Optik einsetzt, ergänzt eine transparente outline in gleicher Stärke. Sie bleibt im Kontrastmodus stehen und bekommt dort die Systemfarbe.
Kann ich den Fokusring animieren?
Ja, outline-offset und outline-color sind animierbar, und ein kurzer Übergang von 150 Millisekunden macht den Ring beim Springen weicher. Die Animation gehört in eine transition, die bei prefers-reduced-motion: reduce entfällt, denn auch kleine Bewegungen zählen zur Bewegung auf der Seite. Wie diese Abfrage funktioniert und wie du sie testest, steht unter CSS-Animationen.
Verwandte Themen
- Tastaturbedienung und sichtbarer Fokus behandelt Anforderung, Test,
tabindexund Fokus-Management. - WCAG 2.4.7 Fokus sichtbar ist die Norm hinter dieser Seite.
- Skip-Links sind das bekannteste Muster aus verstecktem Inhalt und Fokus-Gestaltung.
- CSS-Selektoren erklärt Spezifität und Pseudoklassen im Zusammenhang.
- Farbkontraste zeigt, wie die 3:1-Anforderung gemessen wird.
Quellen
- :focus-visible (MDN: Heuristik und Browser-Unterstützung)
- Understanding SC 2.4.7 Focus Visible (W3C: die normative Anforderung)
- Understanding SC 2.4.13 Focus Appearance (W3C: Mindestfläche und Kontrast des Indikators)
- forced-colors (MDN: Verhalten von outline und box-shadow im Kontrastmodus)