Requires that the keyboard focus indicator is visible whenever a keyboard-operable interface is used.
When you use a keyboard, the focus indicator is your cursor. If you cannot see where focus is, you do not know what a key press will do. Removing the outline with outline: none is one of the most common accessibility mistakes on the web.
This criterion requires that any keyboard-operable user interface has a mode of operation where the keyboard focus indicator is visible. The criterion does not prescribe how the indicator looks. The browser default is acceptable, and so is a custom style.
:focus-visible, as long as there is a mode in which it is visible.Keyboard users, switch users and people who use voice control or other devices that behave like a keyboard. People with attention, short-term memory or executive function difficulties, who need to see where they are. People with low vision, who need a clear indicator. Mouse users also benefit.
The European Accessibility Act (Directive (EU) 2019/882) applies to in-scope products and services placed on the market after 28 June 2025. Recital 47 names four principles for websites and mobile applications: perceivable, operable, understandable and robust. A visible indication of where you are is part of "operable".
The technical counterpart is the standard EN 301 549, which incorporates WCAG 2.4.7 by reference and turns it into separate clauses for each kind of ICT.
| Clause | Type of ICT | What it requires |
|---|---|---|
| 9.2.4.7 | Web pages | Web content must satisfy WCAG success criterion 2.4.7. |
| 10.2.4.7 | Non-web documents (PDF, Office files) | Documents must show a visible keyboard focus indicator where the standard applies the criterion to them. |
| 11.2.4.7 | Non-web software (native mobile apps) | Software must provide a visible keyboard focus indicator. |
Whether and how the criterion applies to non-web documents is stated in clause 10 of the standard. Clause numbers follow the "9. + WCAG number" pattern of EN 301 549. In V3.2.1 the software clause is divided into further subclauses for open and closed functionality. Check the exact numbers in the standard when you cite them.
Standard version: EN 301 549 V4.1.1 (September 2026) is based on WCAG 2.2 and is the first version prepared specifically for the EAA. It has not yet been cited in the Official Journal of the European Union, so for now it is best treated as a voluntary technical route to the EAA's requirements. Once cited, it will give a presumption of conformity. The text of criterion 2.4.7 is the same in WCAG 2.1 and 2.2. It is a Level AA criterion.
A note on EAA scope: Article 2(4) of the Directive excludes certain content from the requirements, for example office file formats published before 28 June 2025 and archives that are not updated after that date. Content you publish or change after that date is not covered by these exclusions.
Directive (EU) 2019/882, EUR-Lex, opens in a new tab
This single line breaks keyboard use on a whole site.
*:focus { outline: none; }/* Keep the default, or replace it with something clearly visible */
:focus-visible {
outline: 3px solid #0b5fff;
outline-offset: 2px;
}:focus-visible shows the indicator for keyboard use and not for mouse clicks.
button:focus { outline: 0; }button:focus-visible {
outline: 3px solid #0b5fff;
outline-offset: 2px;
}A single colour can disappear against some backgrounds. Two colours always contrast with one of them (C40).
a:focus-visible { outline: 2px solid #ffffff; } /* invisible on a white page */a:focus-visible {
outline: 2px solid #ffffff;
box-shadow: 0 0 0 4px #000000;
}Custom controls need their own focus style. Do not rely on the default if you have hidden the native control.
.switch input { position: absolute; opacity: 0; } /* nothing shows focus */.switch input { position: absolute; opacity: 0; }
.switch input:focus-visible + .track {
outline: 3px solid #0b5fff;
outline-offset: 2px;
}Calling blur() on focus defeats keyboard use (F55).
el.addEventListener("focus", () => el.blur());// Let focus stay on the element and style itIn Windows High Contrast mode, author colours are overridden. A transparent outline remains visible there.
.btn:focus-visible { box-shadow: 0 0 0 3px #0b5fff; } /* disappears in forced colours */.btn:focus-visible {
box-shadow: 0 0 0 3px #0b5fff;
outline: 3px solid transparent; /* visible in forced colours */
}Native apps are used with hardware keyboards, switch control and full keyboard access. System controls show focus by default. Custom controls need their own focus indicator.
import SwiftUI
struct TagChip: View {
let title: String
@FocusState private var focused: Bool
var body: some View {
Text(title)
.padding(8)
.focusable()
.focused($focused)
// A custom chip needs its own visible focus indicator
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(focused ? Color.blue : Color.clear, lineWidth: 3)
)
}
}import androidx.compose.foundation.border
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun TagChip(title: String) {
var focused by remember { mutableStateOf(false) }
Text(
text = title,
modifier = Modifier
.onFocusChanged { focused = it.isFocused }
.focusable()
// A custom chip needs its own visible focus indicator
.border(if (focused) 3.dp else 0.dp, Color(0xFF0B5FFF), RoundedCornerShape(8.dp))
.padding(8.dp)
)
}outline: none, outline: 0 and :focus { ... } resets, and check that each is replaced by a visible style.outline: none with no replacement: The most common accessibility mistake on the web.* { outline: 0 }: A global reset removes focus everywhere.blur() on focus.