Browse mode and focus mode bind the same keys to different jobs
Aliases: forms mode · virtual cursor · single-letter navigation
What it is
The same H key is not the same command. In browse mode (virtual cursor) it jumps to the next heading; in focus mode (forms mode) it types the letter into the field. The switch decides who owns the keyboard event: the reader, or the focused widget. This is not a story about whether users like heading navigation. It is about event ownership.
The split is sharpest in Windows web readers. NVDA toggles with Insert+Space; JAWS has an equivalent. Entering a native text field or list box often auto-flips into focus mode and back on the way out.
Why it happens
There is one keyboard. In browse mode the reader is the first consumer: arrows move the virtual cursor, single letters jump by role, digits and punctuation are often claimed too. In focus mode the reader stands down and events reach the control — arrows change the selection, characters insert, shortcuts follow the app’s own bindings.
The second layer is what triggers the auto-switch. Readers treat certain roles as “this widget eats keys”: textbox, combobox, listbox, slider pull focus mode in. A stack of divs that merely looks like a list still has no such role, so the reader stays in browse mode. Arrow keys then walk the virtual cursor off the “options” while the real selection never moves. Custom widgets fail here most often: they look like controls; the keyboard consumer is still the reader.
Studying it
On one page that mixes prose and forms, log the mode at every key (NVDA’s status line, JAWS’s earcon) and what actually happened. Split the task: browse a passage with arrows; then put focus in fields and type, and use arrows on a select. Run NVDA+Firefox and JAWS+Chrome on Windows. VoiceOver’s Quick Nav versus “interact with the control” is the same split under other names; do not test it with Windows Insert keys.
Independent variables: whether the role is a standard form control, whether keyboard handling is custom, whether auto-switch is present. Dependent variables: who consumed the key, whether the task completed, whether the user had to toggle mode by hand to continue.
Where it stops holding
iOS VoiceOver and Android TalkBack do not swallow single letters across a whole page the Windows-web way; gestures and the rotor are the main channels, so the H key is the wrong probe. In native desktop apps focus almost always sits on a widget, and the browse/focus binary is much weaker. Games, editors, and custom shortcuts fight browse-mode single-letter jumps; if the user turns those shortcuts off, the failure changes shape rather than vanishing. Auto-switch often fails in iframes, shadow DOM, and transient popovers: the caret is in a field, and H still jumps headings.
Applying it
- Widgets that must eat arrows or characters need the matching native element or a complete role, plus their own keyboard handling; do not leave the reader thinking it is walking static document text.
- Custom comboboxes, tabs, and grids must take keys on focus and give them back on blur; do not rely on users memorising a manual toggle.
- Do not bind global shortcuts to letters browse mode will claim, unless there is a way to turn them off or a conflict warning.
- How to check: with NVDA, leave the mode toggle untouched, walk prose with
Hand arrows, then Tab into every form control and type. If heading-jump types a letter, or typing jumps elsewhere, ownership is wrong. Repeat in JAWS so the auto-switch is not one reader’s coincidence.
Related
- Same group: J5.09.1 Screen readers speak from a virtual buffer, not from pixels · J5.09.3 Buffer order follows document structure, not CSS visual position · J5.09.4 After dynamic updates the buffer must be rebuilt or speech is stale
- Nearby: J3.01 Keyboard access · J5.07 Compatibility testing
- Search terms:
browse mode·focus mode·forms mode