When visual order and source order disagree, focus jumps
Aliases: tab jump · scrambled focus · visual/source mismatch
What it is
A toolbar looks like Delete, Cancel, Save. Save is float: right, first in the tree. Tab hits Save on the right, then jumps to Delete on the left. The ring stutters right-left as if broken. That is the symptom of two sequences fighting, not a screen-reader-only bug — sighted keyboard users and switch users hit it too; the trail is just visible.
That source order picks the path, and that visual reorder should not rewrite the list, are the previous leaves. This one is the jump: spatially discontinuous focus movement.
Why it happens
Attention and pointing expect spatial continuity: the next target nearby, along the reading direction. Focus follows the tree. When tree and paint fork, the ring teleports across a slab to “the previous visual item,” or from the bottom of the left column to the top of the right and back. Each teleport re-acquires the target; speed drops, misses rise.
Floats, reversed flex, a primary absolutely pinned to the visual bottom are frequent makers. The larger the jump and the more it runs against reading direction, the more it reads as a fault. A small swap on one row hurts less; swapping primary and destructive on a toolbar becomes dangerous.
Studying it
Log the focus ring’s screen coordinates in Tab order as a polyline, and compare it to a “visual reading path” polyline. Independent variable: use of order / float / absolute positioning. Dependent: self-intersections, Euclidean distance between successive foci, jumps against reading direction, keystrokes and misses on a task. Eye tracking is optional, to see whether sighted keyboard users lose gaze when the ring teleports.
If the lab only runs screen-reader users, the effect looks accessibility-specific. Include sighted keyboard users, and it shows up as a layout-projection problem.
Where it stops holding
Two-dimensional widgets (spreadsheet cells, a palette) may move focus on a grid on purpose; that looks like a jump and is a spatial strategy, a different claim. A modal catching focus into the layer is intentional. Jumps here mean inside one layer, inside one reading stream, a ring whose trail runs against visual order or teleports a long way.
Applying it
- Toolbars, footer actions, in-card buttons: write the tree in the visual start-to-end order. Do not float the primary to the right while leaving it first in the tree.
- On a jump, fix the tree or drop the visual reorder. Do not patch with tab-index scripts — that mints a third sequence.
- How to check: film the focus ring and step through. Every move against reading direction, or across empty space wider than one object, is a jump. Map those points back to layout: list the floats,
orders and absolute pins, and delete them until the polyline no longer crosses itself. Then have a keyboard-only user submit; misses should fall near zero.