visible-focus-indication

Any operable UI element must have a visual focus indication.

Who might be affected
Keyboard

Description

For many users who rely on assistive technologies, an absence of a visual focus indicator is like navigating a website or application without being able to see where your cursor is or which button you're about to activate. That's the challenge faced by individuals who use non-pointing input modalities like:

  • Keyboards: They tab through elements to move around.
  • Switch access: They use a limited number of switches to interact with the interface.

These users depend entirely on the visual focus indicator to understand which element is currently active and where they are within the interface's flow. Without this clear visual cue, they're left without any way to perceive their location or identify what actions they can take. In essence, a missing focus indicator renders the interface unusable for them.

Note: In cases where a focus indicator technically exists but the indicator contrast is too low or the amount of modified pixels would not be discernible to a user, this test prioritizes the visibility and usability of the focus indication. This is because an invisible or practically invisible indicator doesn't fulfill the user's need to perceive focus, which is the core principle of Success Criterion 2.4.7 Focus Visible

Quick Fixes

In general, unlike on the web, on mobile platforms it is difficult to override the focus indication. Here are some examples to how focus indication may break and how it can be solved:

Fail Patterns

Android XML Views

1<?xml version="1.0" encoding="utf-8"?>
2<selector xmlns:android="http://schemas.android.com/apk/res/android">
3 <!-- No focused state -->
4 <item android:drawable="@drawable/button_pressed" android:state_pressed="true"/>
5 <item android:drawable="@drawable/button_default"/>
6</selector>

Pass Patterns

Android XML Views (XML)

1android:background="@drawable/my_selector"
2<!-- in drawable/my_selector.xml -->
3<?xml version="1.0" encoding="utf-8"?>
4<selector xmlns:android="http://schemas.android.com/apk/res/android">
5 <item android:drawable="@drawable/button_focused" android:state_focused="true"/>
6 <item android:drawable="@drawable/button_pressed" android:state_pressed="true"/>
7 <item android:drawable="@drawable/button_default"/>
8</selector>

Android XML Views (Code)

1setWillNotDraw(false)
2...
3setOnFocusChangeListener { v, hasFocus ->
4 background = if (hasFocus) {
5 ContextCompat.getDrawable(context, ...)
6 } else {
7 ContextCompat.getDrawable(context, ...)
8 }
9}

Jetpack Compose

1val interactionSource = remember { MutableInteractionSource() }
2Modifier...
3 .focusable(interactionSource = interactionSource)
4 .border(1.dp, if (interactionSource. collectIsFocusedAsState().value) LightGrey else Transparent)
5
6// OR
7Modifier...
8 .background(color = if (focused) Color.LightGray else Color.Transparent)

iOS

Sometimes, the focus indication—which highlights interactive elements—can be hard to see if its color closely matches the background of the element itself. While developers don't have control over this display, you can resolve it by customizing the focus indicator's color on your device. Navigate to Settings → Accessibility → Keyboard & Typing (under Accessories) → Full Keyboard Access → Color, and select a color that provides better contrast.

iOS "Focus Indicator Color" settings screen with "Default" selected for the focus indicator. Other options are Gray, White, Blue, Red, Green, Yellow, and Orange.

How Users Are Affected

Since users of some assistive technology do not directly point to the controls on the UI as a mouse user would, they need some indication of the currently active control. When such an indication is not present, the reliability of the interface is compromised, and users will lose confidence and may avoid using controls and even abandon the interface.

WCAG Success criteria

This issue might cause elements to fail one or more of the following Success criteria:
2.4.7 Focus Visible (AA)

Understanding Success Criterion 2.4.7 Focus Visible