Search topics
Dropdowns and fields that change the page on their own
A sort menu reloads the page as soon as its value changes, and a date field pulls focus into its calendar the moment it is focused.
<select onchange="this.form.submit()"> The problem
Keyboard and screen reader users are sent away, or pulled ahead, before they have chosen anything.
A stationery shop lists its pens under a "Sort by" menu. Someone using a keyboard tabs to the menu and presses the down arrow to see what the other orders are. On Windows, the arrow changes a closed select's value straight away, and most browsers fire change at once, so the page reloads in the second order. Focus goes back to the top of the page. To try the third order, the person has to tab all the way down again, and every arrow press sends them back up.
The same shop's checkout has a delivery date field with a calendar. As soon as the field receives focus, the calendar opens and its script moves focus to the first day. Nobody can type a date, and pressing Shift+Tab to go back lands on the field again, which throws focus forward into the calendar once more.
WCAG calls these changes of context: a new page, a new window, focus moved somewhere else, or content rearranged so much that the page means something else. Success Criterion 3.2.2 On Input says changing a control's value must not cause one unless people were told beforehand. Success Criterion 3.2.1 On Focus is stricter: receiving focus must never cause one, and it has no exception. The sort menu reloads the page on input, and the date field moves focus on focus.
Mouse users rarely notice, because a mouse opens the list and picks one option with one click. The problem belongs to everyone who moves through a page a step at a time.
4 of 10 groups affected
- No vision (affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited manipulation Keyboard and switch users choose by stepping through the options, so the first step already reloads the page. A field that throws focus forward can't be reached again with Shift+Tab.
- Without vision Screen reader users browse a select with the arrow keys, then hear a new page start reading from the top, with nothing to say why.
- Limited vision A magnifier user zoomed in on the select is carried back to the top of the page by the reload, and has to find their way back to it.
- Limited language, cognitive and learning abilities A page that changes before anything is pressed is hard to follow, and people may not know their choice was applied or how to change it back.
The markup is valid and every control has a label, so axe and similar scanners report nothing. The failure lives in a script that runs on focus or change, and only shows when someone presses the keys. A scan that clicks the select with a mouse picks one option and sees the reload as intended. AI tools asked to "make the select update the page" tend to write exactly the onchange handler shown below.
Try it
Change a field with the keyboard, and watch where focus goes.
In Broken 1, press ↓ in Sort by and watch where focus goes. In Broken 2, Tab to Delivery date, then press Shift+Tab to go back to Name.
Broken Can you fix this?
Pens
- Fineliner
- Gel pen
- Brush pen
- Fountain pen
Press Tab until Sort by is focused, then press ↓.
Focus is on: not in the page yet
The fix
Wait for a button, or make the change in place and leave focus where it is.
- 1Focusing a control never moves focus, opens a window or leaves the page.
- 2A new value changes the page only after a button press, or in place with focus left on the control.
- 3Whatever changes appears next to the control that changed it.
A sort menu that reloads on change
<form action="/pens" method="get"> <label for="sort">Sort by</label> <select id="sort" name="sort" onchange="this.form.submit()"> <option value="popular">Most popular</option> <option value="name">Name, A to Z</option> <option value="new">Newest</option> </select></form>A button that applies the choice
<form action="/pens" method="get"> <label for="sort">Sort by</label> <select id="sort" name="sort"> <option value="popular">Most popular</option> <option value="name">Name, A to Z</option> <option value="new">Newest</option> </select> <button type="submit">Sort</button></form> <label for="date">Delivery date</label><p id="date-format">For example, 2026-12-14</p><input id="date" name="date" aria-describedby="date-format"><button type="button" id="date-button" aria-expanded="false" aria-controls="calendar">Choose date</button>Every new value submits the form, and a keyboard makes a new value at each arrow press. The reload puts focus back at the top of the page.
The select and the field do nothing by themselves. The page reloads when someone presses Sort, and the calendar opens, taking focus, when someone presses Choose date: both are changes people asked for. The field also accepts a typed date, so the calendar is a help, not the only way in. Choosing a day fills the field, and choosing a day or pressing Escape closes the calendar and returns focus to Choose date.
Both pass both criteria. The button is the smallest change, works without JavaScript, and suits any choice that has to load a new page, such as a category or a region; it costs one more Tab stop and a press. The change in place saves that press and feels quicker, but it needs script that re-renders without moving focus or scrolling, and a status message. Use the button when the choice leads to another page, and the change in place when the page can apply the choice itself.
Telling people beforehand ("Choosing an order reloads the page") makes the sort menu pass 3.2.2, but it does not help the date field, because 3.2.1 has no such exception. It also leaves keyboard users sent away by the first option they pass, so treat it as a last resort for a control you cannot change.
Some patterns are not changes of context, and need no button.
- A tooltip or hint shown on focus: it adds content next to the control and leaves focus alone.
- A section shown when a checkbox is ticked, such as a separate billing address: content appears after the control, and focus stays on it.
- A list filtered as someone types in a search field: the page stays, and focus stays in the field.
Keep auto-advance out of split fields too. Moving focus to the next box once a box is full is a change of context on input, and it surprises people who check what they typed or correct a digit. A single field for the whole value avoids the problem.
If a component library opens its date picker on focus, look for an option to open it from a button instead, or wrap it so the field keeps focus. A month-sized calendar should be a single Tab stop with arrow keys inside it, as in the APG date picker dialog, rather than thirty Tab stops.
Fixing this with an AI coding assistant? Get this guide as Markdown
Verify the fix
5 checks, no mouse.
Test with: Keyboard, Screen reader, Zoom
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared form or filter components change.
Limits
This is a starting pattern, not a guarantee for every application. Browsers differ in when they fire change from the keyboard: on macOS the arrow keys open the list, and the value changes when it is confirmed. Test with the platforms your users have, and with the components your site really uses.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.