:focus-visible – der Fokusrahmen, den nur Tastaturnutzer sehen
outline: none ist der meistkopierte und schädlichste CSS-Schnipsel überhaupt: Danach kann niemand mehr per Tastatur navigieren. :focus-visible löst genau das Problem, das man damit lösen wollte – ohne den Schaden.
Diese drei Zeilen findet man in erschreckend vielen Stylesheets:
/* ⚠️ bitte nicht */
*:focus { outline: none; }Der Grund dafür ist nachvollziehbar: Beim Klick auf einen Button erscheint ein blauer Rahmen, der nicht ins Design passt. Die Folge ist allerdings, dass niemand mehr sehen kann, wo er gerade ist, wenn er mit der Tabulatortaste durch ein Formular geht. Für Menschen, die keine Maus benutzen — aus welchem Grund auch immer — ist die Seite damit praktisch unbedienbar.
Der Browser weiß, wie du gekommen bist
Genau dafür gibt es :focus-visible. Der Browser unterscheidet, wie ein Element den Fokus bekommen hat: per Klick oder per Tastatur. Und nur im zweiten Fall greift die Regel.
/* Standard-Rahmen weg – aber nur für Mausklicks */
:focus:not(:focus-visible) {
outline: none;
}
/* Für Tastaturnutzer: deutlich sichtbar, im eigenen Design */
:focus-visible {
outline: 3px solid var(--akzent, #0f766e);
outline-offset: 3px;
border-radius: 4px;
}Das ist die ganze Lösung. Der Klick auf einen Button hinterlässt keinen Rahmen mehr, das Durchtabben durch ein Formular dagegen schon — deutlich sichtbar und in deiner eigenen Farbe.
Bei Textfeldern zeigt der Browser den Fokus übrigens auch beim Klicken an, weil dort der Cursor blinkt und die Stelle ohnehin klar ist. Diese Feinheiten muss man nicht selbst regeln, sie stecken schon in der Definition.
outline statt border oder box-shadow
Ein häufiger Umweg ist, den Fokus über border zu markieren. Das verschiebt das Layout um zwei Pixel und lässt alles hüpfen. outline liegt außerhalb des Kastens und beeinflusst die Größe nicht — dafür ist es gemacht. outline-offset schiebt es zusätzlich ein Stück nach außen, damit es nicht am Element klebt.
Kontrast nicht vergessen
Ein Fokusrahmen, der zum Hintergrund kaum Kontrast hat, ist genauso wenig hilfreich wie gar keiner. Die Anforderung aus WCAG 2.1 für solche Elemente liegt bei 3:1 gegen die Umgebung. Bei einem hellen Hintergrund fällt ein dunkler Teal-Ton locker darüber; bei einem dunklen Design braucht es einen hellen Rahmen.
Wenn du sowohl einen hellen als auch einen dunklen Modus hast, prüfe beide. Eine Farbe, die in einem Modus gut sitzt, kann im anderen fast unsichtbar sein.
Und die Reihenfolge?
:focus-visible hilft nur, wenn überhaupt etwas fokussierbar ist. Ein <div onclick="…"> ist es nicht — dort landet man beim Tabben nie. Wenn etwas anklickbar sein soll, nimm ein <button> oder <a>. Das ist keine Formalie: Damit bekommst du Tastaturbedienung, Fokus, die richtige Ansage im Screenreader und die Enter-Taste geschenkt, ohne eine Zeile JavaScript.
Barrierefreiheit klingt nach viel Arbeit, ist an dieser Stelle aber ein Fünf-Zeilen-CSS und die Entscheidung, das richtige HTML-Element zu nehmen. Diese beiden Dinge decken schon einen großen Teil dessen ab, woran Websites in der Praxis scheitern.
Du bist unsicher, wie zugänglich deine Seite eigentlich ist? Der Tab-Test ist der schnellste Einstieg: Maus weglegen und nur mit der Tabulatortaste durch die Seite gehen. Wenn du dabei irgendwann nicht mehr weißt, wo du bist, hast du dein erstes Ergebnis. Schreib mir, wenn du dabei Unterstützung willst.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
accent-color – Checkboxen und Regler in deiner Markenfarbe, in einer Zeile
Checkboxen und Radiobuttons waren jahrelang der Grund, warum Leute sie mit appearance: none nachgebaut haben – und dabei die Tastaturbedienung verloren. Eine einzige CSS-Eigenschaft macht das überflüssig.
Verschachteltes CSS – ganz ohne Sass, direkt im Browser
Das Feature, für das die meisten Leute überhaupt erst einen CSS-Präprozessor eingerichtet haben, kann der Browser inzwischen selbst. Kein Build-Schritt, keine Abhängigkeit – nur ein paar Regeln, die man kennen sollte.
Text nach drei Zeilen abschneiden – line-clamp statt JavaScript
Kartenlisten sehen nur dann ordentlich aus, wenn alle Vorschautexte gleich hoch sind. Das serverseitig auf 120 Zeichen zu kürzen geht schief, sobald die Karte schmaler wird – CSS kann das seit Jahren selbst.