focus-within vs. focus-visible: Der Vergleich
AI generated
{ }
@
CSS · Selektoren · Barrierefreiheit
focus-within vs. focus-visible: Der Vergleich
Gruppenkontext gegen tastaturbewusste Sichtbarkeit

focus-within und focus-visible klingen ähnlich, lösen aber grundverschiedene Probleme. Der eine reagiert auf Fokus irgendwo innerhalb eines Containers, der andere unterscheidet zwischen Tastatur- und Mausinteraktion. Wer beide verwechselt, baut entweder unruhige Fokusringe oder unsichtbare Tastaturnavigation.

16 Min. Lesezeit focus-within · focus-visible · Barrierefreiheit Alle modernen Browser

1. Warum zwei ähnliche Fokus-Pseudoklassen existieren

Wer focus-within und focus-visible zum ersten Mal nebeneinander sieht, vermutet leicht, dass es sich um zwei Varianten desselben Konzepts handelt. Tatsächlich lösen beide Pseudoklassen völlig unterschiedliche Probleme, die historisch getrennt entstanden sind. focus-within beantwortet die Frage, ob sich der Fokus irgendwo innerhalb eines Containers befindet, egal auf welchem Kindelement. focus-visible hingegen beantwortet die Frage, ob ein sichtbarer Fokusring angezeigt werden sollte, basierend auf der Art der Interaktion, mit der der Fokus zustande kam.

Diese Unterscheidung ist entstanden, weil klassisches :focus zwei Anwendungsfälle gleichzeitig bedienen musste, die sich gegenseitig störten: Entwickler wollten schicke, gruppierte Fokuseffekte für Formulare, gleichzeitig aber keinen hässlichen blauen Ring bei jedem Mausklick auf einen Button. Vor focus-visible mussten Teams JavaScript-Bibliotheken wie focus-visible-polyfill einsetzen, um zwischen Tastatur- und Mausinteraktion zu unterscheiden. Beide Pseudoklassen zusammen ergeben heute ein vollständiges, natives Werkzeug für durchdachtes Fokus-Design.

2. focus, focus-within und focus-visible im Detail

:focus trifft exakt auf das Element zu, das gerade den Tastaturfokus oder Programmfokus trägt, unabhängig davon, wie der Fokus zustande kam. :focus-within trifft auf ein Element zu, wenn es selbst oder irgendein Nachfahre den Fokus trägt, was es zum idealen Werkzeug macht, um einen ganzen Container zu markieren, sobald eines seiner Kinder aktiv ist. :focus-visible schließlich trifft nur dann zu, wenn der Browser entscheidet, dass ein sichtbarer Indikator angemessen ist, typischerweise bei Tastaturnavigation, nicht aber bei einem einfachen Mausklick.

Die Heuristik hinter :focus-visible ist browserintern implementiert und berücksichtigt unter anderem die Eingabemethode, den Elementtyp und ob das Element von Natur aus interaktiv ist. Ein button, der per Maus geklickt wird, erhält typischerweise keinen sichtbaren Fokusring, während derselbe button per Tabulatortaste erreicht durchaus einen Ring bekommt. Ein Textfeld hingegen zeigt oft auch bei Mausklick einen Fokusindikator, weil der Text-Cursor selbst schon eine Art Fokusanzeige ist und Nutzer trotzdem wissen sollten, dass das Feld aktiv ist.


/* :focus matches regardless of interaction method */
button:focus {
  outline: 2px solid #7c3aed;
}

/* :focus-within matches the container when any child has focus */
.form-group:focus-within {
  background: #f5f3ff;
  border-color: #7c3aed;
}

/* :focus-visible matches only when the browser deems it necessary */
button:focus-visible {
  outline: 2px solid #7c3aed;
  outline-offset: 2px;
}

/* Common pattern: remove default outline, restore only when visible */
button:focus:not(:focus-visible) {
  outline: none;
}

3. focus-within in der Praxis: Gruppen und Custom Components

focus-within zeigt seinen Wert überall dort, wo mehrere Kindelemente logisch zu einer Einheit gehören, aber einzeln fokussierbar sind. Ein Suchfeld mit separatem Such-Button ist ein typisches Beispiel: statt nur das Input-Feld zu markieren, soll der gesamte umgebende Container hervorgehoben werden, unabhängig davon, ob gerade das Eingabefeld oder der Button den Fokus trägt. .search-box:focus-within { box-shadow: 0 0 0 3px rgba(124,58,237,0.3); } löst das mit einer einzigen Regel, ohne JavaScript und ohne dass jedes Kindelement einzeln behandelt werden muss.

Ein zweites verbreitetes Einsatzgebiet ist die Navigation mit Dropdown-Menüs. Ein Menüpunkt mit Untermenü soll geöffnet bleiben, solange sich der Fokus irgendwo innerhalb des Untermenüs befindet, etwa während ein Nutzer per Tabulatortaste durch die Einträge navigiert. li:focus-within > ul { display: block; } hält das Untermenü sichtbar, solange ein beliebiges Kindelement fokussiert ist, und schließt es automatisch, sobald der Fokus den Container verlässt. Diese Technik funktioniert ganz ohne JavaScript und bleibt dabei vollständig tastaturzugänglich.


/* Highlight the whole search box regardless of which child has focus */
.search-box:focus-within {
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.3);
  border-color: #7c3aed;
}

/* Dropdown stays open while focus is anywhere inside the submenu */
nav li {
  position: relative;
}

nav li > ul {
  display: none;
  position: absolute;
  top: 100%;
}

nav li:focus-within > ul,
nav li:hover > ul {
  display: block;
}

4. focus-visible in der Praxis: Tastatur von Maus unterscheiden

Der klassische Konflikt, den focus-visible löst, betrifft Buttons und Links: Designer möchten keinen sichtbaren Ring bei jedem Mausklick, Entwickler brauchen aber trotzdem einen deutlichen Indikator für Tastaturnutzer. Vor focus-visible war die häufigste, aber barrierefreiheitswidrige Lösung ein globales *:focus { outline: none; }, das den Fokusring komplett entfernte und Tastaturnutzer komplett aussperrte. focus-visible macht diese Praxis überflüssig: button:focus-visible { outline: 2px solid #7c3aed; } zeigt den Ring nur, wenn der Browser die Interaktion als tastaturbasiert einstuft.

Für maßgeschneiderte Komponenten wie Custom-Checkboxen oder Karten mit tabindex lohnt sich das Muster, den Standard-Outline zu entfernen und einen eigenen, deutlich sichtbaren Ersatz nur unter :focus-visible zu setzen. So bleibt das visuelle Design bei Mausinteraktion unverändert, während Tastaturnutzer weiterhin exakt erkennen können, wo sich der Fokus gerade befindet. Wichtig: :focus-visible ersetzt niemals ersatzlos den Fokusindikator, es verschiebt nur, wann er sichtbar wird.


/* Custom card component with a visible, keyboard-only focus ring */
.card[tabindex="0"] {
  outline: none;
}

.card[tabindex="0"]:focus-visible {
  outline: 3px solid #7c3aed;
  outline-offset: 3px;
  border-radius: 0.5rem;
}

/* Custom checkbox: visible ring only for keyboard interaction */
.checkbox-input:focus-visible + .checkbox-visual {
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.4);
}

5. Kombination beider Pseudoklassen für barrierefreie Komponenten

Die stärkste Wirkung entfalten focus-within und focus-visible in Kombination. Ein Formularfeld mit Label und Hilfetext kann per focus-within den gesamten Block hervorheben, während innerhalb des Blocks per focus-visible nur bei Tastaturnutzung ein zusätzlicher Ring auf dem Input erscheint. Das ergibt ein zweistufiges Feedback: die grobe Gruppen-Hervorhebung für alle Interaktionsarten, die feine, tastaturspezifische Ringmarkierung für Nutzer, die per Tab navigieren.

Ein weiteres Kombinationsmuster betrifft komplexe Widgets wie Datepicker oder Comboboxen mit mehreren internen Elementen. .datepicker:focus-within { z-index: 20; } stellt sicher, dass das Widget über anderen Elementen liegt, solange irgendein Teil davon fokussiert ist, während :focus-visible an den einzelnen Tagesknöpfen für die konkrete Tastaturnavigation innerhalb des Kalenders sorgt. Diese Aufteilung der Zuständigkeiten, Gruppen-Kontext gegen individuelle Sichtbarkeit, ist der Kern eines durchdachten Fokus-Systems.

6. Fallstricke: doppelte Ringe und verschwindende Outlines

Ein häufiger Fehler ist, sowohl :focus als auch :focus-visible gleichzeitig mit sichtbarem Outline zu definieren, ohne den einen gegen den anderen abzugrenzen. Das Ergebnis sind doppelte, sich überlagernde Ringe oder ein Ring, der bei Mausklick erscheint, obwohl genau das vermieden werden sollte. Die saubere Lösung ist das Muster :focus:not(:focus-visible) { outline: none; } gefolgt von einer eigenen Regel für :focus-visible, sodass beide Zustände sich niemals widersprechen.

Ein zweiter Fallstrick betrifft Frameworks und Utility-Klassen, die pauschal outline: none auf alle interaktiven Elemente setzen, ohne einen Ersatz zu definieren. Das entfernt Fokusindikatoren komplett und macht die Seite für Tastaturnutzer unbedienbar, ein klarer Verstoß gegen WCAG 2.4.7. Wer outline: none in einem globalen Reset findet, sollte sofort prüfen, ob an anderer Stelle ein :focus-visible-Ersatz existiert, bevor die Regel als unproblematisch eingestuft wird.

7. Browser-Unterstützung und Fallback-Strategien

focus-within wird von allen aktuellen Browsern seit mehreren Jahren unterstützt und gilt als sicher einsetzbar, selbst in Projekten mit konservativen Browser-Anforderungen. focus-visible ist ebenfalls in allen aktuellen Evergreen-Browsern vertreten, war aber lange Zeit nur über einen JavaScript-Polyfill verfügbar. Für Projekte, die noch ältere Browser unterstützen müssen, ist die Kombination aus nativem :focus-visible und einem Fallback via @supports not selector(:focus-visible) sinnvoll, um in älteren Umgebungen auf ein einfaches, immer sichtbares :focus-Styling zurückzufallen.

Wichtig ist, den Fallback niemals so zu gestalten, dass er den Fokusindikator komplett entfernt. Lieber ein sichtbarer Ring zu viel bei einem Mausklick in einem alten Browser als ein komplett unsichtbarer Fokus für Tastaturnutzer. Die Fallback-Strategie sollte also konservativ in Richtung Sichtbarkeit gehen, nicht in Richtung Unsichtbarkeit, selbst wenn das ästhetisch nicht perfekt ist.

8. Custom Focus-Styles ohne Barrierefreiheit zu brechen

Ein individuell gestalteter Fokusindikator muss weiterhin die Kernanforderungen der Barrierefreiheit erfüllen: ausreichender Kontrast zum Hintergrund, eine Mindestdicke und ein klar erkennbarer Unterschied zum unfokussierten Zustand. WCAG 2.4.11 verlangt, dass der Fokusindikator nicht vollständig von anderen Inhalten verdeckt wird und einen Mindestkontrast von 3:1 zur Umgebung aufweist. Ein rein farblicher Unterschied ohne Kontur oder Schatten reicht oft nicht aus, insbesondere für Nutzer mit eingeschränktem Farbsehen.

Beim Design eigener Fokusringe empfiehlt sich outline gegenüber border, weil outline keinen Platz im Layout beansprucht und sich nicht auf die Boxgröße auswirkt. outline-offset schafft zusätzlichen visuellen Abstand zum Element, was besonders bei kleinen, eng beieinander liegenden interaktiven Elementen die Erkennbarkeit deutlich verbessert. Kombiniert mit :focus-visible lässt sich so ein Fokusring gestalten, der zum Corporate Design passt, ohne die Anforderungen der Barrierefreiheit zu verletzen.

9. Vergleichstabelle: wann welche Pseudoklasse

Die folgende Tabelle fasst zusammen, welche Pseudoklasse für welchen konkreten Anwendungsfall die richtige Wahl ist, damit die Entscheidung im Projektalltag schnell und konsistent getroffen werden kann.

Anwendungsfall :focus :focus-within :focus-visible
Einzelnes Input-Feld hervorheben Passend Nicht nötig Für Ringe empfehlenswert
Formulargruppe mit mehreren Kindern Reagiert nicht Passend Zusätzlich für Ring nutzbar
Button-Ring nur bei Tastatur Zeigt Ring immer Nicht relevant Passend
Dropdown offen halten Nur bei direktem Fokus Passend Nicht relevant
Textfeld mit Cursor Ausreichend Nicht nötig Meist trotzdem sichtbar

Als Faustregel gilt: focus-within für Gruppen und Container, focus-visible für einzelne interaktive Elemente, bei denen Maus- und Tastaturinteraktion unterschiedlich behandelt werden sollen. Beide lassen sich problemlos gemeinsam in einer Komponente einsetzen, ohne sich gegenseitig zu stören.

Mironsoft

Barrierefreie Frontends, moderne CSS-Architektur und Hyvä-Themes

Fokus-Management, das Tastaturnutzer wirklich sehen können?

Wir prüfen bestehende Komponenten auf WCAG-konforme Fokusindikatoren und setzen focus-within sowie focus-visible gezielt für barrierefreie, gut bedienbare Oberflächen ein.

Fokus-Audit

Tastaturnavigation und Fokusindikatoren gegen WCAG 2.4.7 und 2.4.11 prüfen

Komponenten-Refactoring

focus-within und focus-visible in bestehende Custom Components integrieren

Design-System

Konsistente, markenkonforme Fokusringe für alle interaktiven Elemente

10. Zusammenfassung

focus-within und focus-visible lösen unterschiedliche Probleme und ergänzen sich, statt sich zu ersetzen. focus-within markiert einen Container, sobald irgendein Kindelement den Fokus trägt, ideal für Formulargruppen, Suchfelder und Dropdown-Menüs. focus-visible entscheidet, ob ein Fokusring passend zur Eingabemethode angezeigt wird, und löst damit den historischen Konflikt zwischen sauberem Mausdesign und zugänglicher Tastaturnavigation.

Wer beide Pseudoklassen gezielt kombiniert, kann Komponenten bauen, die visuell aufgeräumt wirken und gleichzeitig vollständig barrierefrei bedienbar sind. Das pauschale Entfernen von Fokusindikatoren mit outline: none ohne Ersatz bleibt dabei in jedem Fall ein Fehler, unabhängig davon, wie gut die restliche Komponente gestaltet ist. Die vorgestellten Muster lassen sich direkt in bestehende Formulare, Navigationen und Custom Components übernehmen.

focus-within vs. focus-visible: Das Wichtigste auf einen Blick

focus-within

Markiert einen Container, sobald irgendein Nachfahre den Fokus trägt. Ideal für Gruppen, Suchfelder und Dropdowns.

focus-visible

Zeigt den Fokusring nur, wenn der Browser die Interaktion als tastaturbasiert einstuft. Löst den Maus-Tastatur-Konflikt.

Kombination

focus-within für den groben Container, focus-visible für den feinen Ring am Element, beides gemeinsam nutzbar.

Barrierefreiheit

outline: none ohne Ersatz ist immer ein Fehler. Mindestkontrast 3:1 und klare Sichtbarkeit sind Pflicht.

11. FAQ: focus-within vs. focus-visible

1Hauptunterschied focus-within vs. focus-visible?
focus-within markiert Container bei Kindfokus, focus-visible entscheidet nach Interaktionsmethode, ob ein Ring erscheint.
2Können beide zusammen verwendet werden?
Ja, empfohlen: focus-within für die Gruppe, focus-visible für den feinen Ring am einzelnen Element.
3Warum kein outline: none?
Ohne Ersatz macht es die Seite für Tastaturnutzer unbedienbar, ein Verstoß gegen WCAG 2.4.7.
4Ring bei Textfeldern auch per Maus?
Oft ja, weil Browser hier auch bei Mausklick einen sichtbaren Fokus als sinnvoll einstufen.
5Dropdown offen halten bei Fokus?
li:focus-within > ul { display: block; } hält das Menü offen, solange der Fokus irgendwo innerhalb liegt.
6Was macht focus:not(:focus-visible)?
Entfernt den Standardring bei nicht tastaturbasierter Interaktion und verhindert widersprüchliche Fokusstile.
7Wird focus-within überall unterstützt?
Ja, seit Jahren in allen aktuellen Browsern, gilt als sicher einsetzbar.
8Welcher Kontrast ist Pflicht?
Mindestens 3:1 laut WCAG 2.4.11, plus ausreichende Sichtbarkeit ohne Verdeckung.
9Warum outline statt border?
outline beansprucht keinen Layout-Platz, border verschiebt umliegende Elemente und verursacht Sprünge.
10Fallback ohne focus-visible?
@supports not selector(:focus-visible) liefert ein immer sichtbares :focus-Styling als sichere Alternative.