A hotel booking site's room-rate radio group reloads the page and moves focus to the top on every change; why does that break keyboard users, and what is the fix?
answer
- arrows move and check together
- passing an option selects it
- a change of context on input
- WCAG 2.2 3.2.2
- update in place, keep focus
basics
~20 sIn a radio group, arrow keys move focus and check the option in one step, so reaching the third rate fires two reloads that throw focus away. Update the price in place without moving focus, or apply the choice on an explicit action.
solid answer
~50 sThe Authoring Practices radio group contract ties selection to movement: Tab enters the group on the checked radio, or the first if none is checked, and Up/Down or Left/Right move focus **and** check the newly focused radio, wrapping at the ends. A pointer user clicks the third rate once; a keyboard user passes through the second on the way and triggers a reload there, lands at the top of the page, and has to find the group again, forever. Moving focus and loading a new page are changes of context, and **WCAG 2.2 3.2.2 On Input** (level A) forbids triggering one automatically when a setting changes unless people are told beforehand. The fix is to keep a radio change non-destructive: update the price summary in place, leave focus on the radio, and announce the new total politely as a status message; if the recalculation is expensive, apply it on an explicit 'Update price' or 'Continue' action instead.
go deeper
Know that in a radio group the arrow keys both move and select, so every option passed on the way is chosen.
Explain the full Authoring Practices keyboard contract, including where focus lands on entry and the toolbar exception.
Diagnose why this shipped, pointer-only testing and valid markup, connect it to 3.2.2 On Input, and choose between in-place update and deferred apply.
Write the rule into the system: single-choice changes never change context, with a status-message pattern teams reuse instead of wiring reloads per form.
## The keyboard contract of a radio group A **radio group** is a set of options where no more than one can be checked. The WAI-ARIA Authoring Practices define its keyboard behaviour, for groups not inside a toolbar: 1. **Tab** and **Shift+Tab** move focus into and out of the group as a single stop. 2. On entering, focus lands on the **checked** radio; if none is checked, on the **first** radio. 3. **Space** checks the focused radio if it is not already checked. 4. **Down/Right Arrow** moves focus to the next radio, unchecks the previous one and **checks** the new one, wrapping from last to first. 5. **Up/Left Arrow** does the same in the other direction. The important consequence for design is that, for keyboard users, **moving through the options is choosing them**. There is no way to look at 'Semi-flexible' on the way from 'Non-refundable' to 'Flexible' without selecting it. ## Why a reload on change breaks that contract - **Intermediate options fire.** A keyboard user heading for the third rate triggers a reload on the second. - **Focus is thrown away.** After the reload, focus sits at the top of the page. The person has to navigate back to the group, every time. - **Screen-reader users lose their place.** They hear a new page start reading instead of the option they moved to. - **The bug hides from pointer testing.** A mouse click selects the target directly, so the team that tests only with a pointer sees nothing wrong. - **Automated scanners rarely catch it**, because the markup can be perfectly valid; the failure is in behaviour. ## What WCAG 2.2 says **3.2.2 On Input** (level A): changing the setting of any user interface component does not automatically cause a **change of context** unless the user has been advised of the behaviour before using the component. WCAG's definition of a change of context includes moving **focus** to a different component and going to a **new page**. A reload that moves focus to the top does both. Updating content in place, such as a price, is not by itself a change of context, as long as focus stays put and the page is not significantly rearranged. ## Fixes, ranked | Fix | Focus stays on the radio? | Cost | |---|---|---| | Update the price summary in place and announce it as a status message | Yes | A small client-side update and a polite announcement | | Defer the recalculation to an explicit 'Update price' or 'Continue' action | Yes | One extra step for everyone | | Keep the reload but warn beforehand | No | Technically allowed by 3.2.2, still painful for keyboard users | | Reload and try to restore focus afterwards | Sometimes | Fragile, slow, and still fires on every intermediate option | The first option is usually best: WCAG 2.2 **4.1.3 Status Messages** (level AA) expects a message like 'Total now 412 for 3 nights' to reach assistive technology without moving focus. The second is the safe fallback when the recalculation is slow or costly. ## How to catch it before release 1. Walk every single-choice control with the keyboard alone, moving through all options with the arrow keys. 2. After each change, check where focus is and whether the page reloaded or scrolled. 3. Repeat with a screen reader and listen for an unexpected new page starting to read. 4. Add the rule to the component's review checklist, so a product team wiring a new rate selector meets it before release rather than in a complaint. ## A note on toolbars The Authoring Practices make one exception: a radio group **inside a toolbar** uses arrows to move focus without changing which radio is checked, because arrows there navigate the whole toolbar. A booking form's rate choice is not a toolbar, so the standard contract applies. ## Across platforms Native mobile platforms present single-choice lists and segmented selectors with their own focus models for keyboards and switch access, and the same rule holds: selecting an option must not navigate away or reset focus. A system spec should state the rule, **changing a single-choice selection never changes context**, and let each platform implement it.
- Is it acceptable if the page warns 'Changing the rate reloads the page' above the radio group?It satisfies the letter of 3.2.2, which allows a change of context when people are advised beforehand, but it leaves keyboard users paying a reload for every intermediate option. It is a floor, not a fix; updating in place or deferring to an explicit action is still the better design.
- Why do radio buttons inside a toolbar behave differently with the arrow keys?In a toolbar, arrow keys move between all the toolbar's controls, so the Authoring Practices say arrows move focus without changing which radio is checked; Space, or optionally Enter, checks the focused one. Otherwise simply passing through the toolbar would change settings. Outside a toolbar, arrows move and check together.
saying these in an interview costs you the question
- Arrow keys only move focus in a radio group; Space is what selects.
- Reloading on change is fine because mouse users click the option they want directly.
- Restoring focus after the reload fully solves the problem.
- Updating a price elsewhere on the page always counts as a change of context.
- An automated accessibility scan would have flagged this before release.