Finding PCV-001
Keyboard focus is trapped inside the payment method menu at checkout
What is wrong
Once the payment method menu is opened from the keyboard, there is no keyboard way out of it. Tab and Shift+Tab only cycle between the four payment options, and Escape does nothing. The only way to close the menu is to click outside it with a mouse.
Who it affects
Anyone who cannot use a mouse: keyboard users, screen reader users, switch and voice control users. They cannot reach the “Place order” button, so they cannot complete a purchase at all. This blocks the main task of the site, which is why it is rated critical.
Steps to reproduce
- Add any item to the basket and go to
/checkout. - Fill in the delivery details and continue to step 3, “Payment”.
- Put the mouse aside. Press Tab until focus reaches the “Payment method” button (the first control after the order summary).
- Press Enter. The menu opens with four options: Card, UPI, Net banking, Cash on delivery.
- Press Tab. Focus moves to Card. Keep pressing Tab: focus goes to UPI, Net banking, Cash on delivery, then back to Card.
- Press Escape. The menu stays open and focus does not move.
- Press Shift+Tab repeatedly. Focus keeps cycling inside the menu and never reaches the page.
Expected
Escape closes the menu and returns focus to the “Payment method” button. Tab from the last option leaves the menu and moves to the next control, so “Place order” can be reached.
Actual
Focus is held inside the menu. With NVDA running, the options are announced again and again with no way out. The order cannot be placed without a mouse.
How to fix
Remove the script that sends focus from the last option back to the first: a menu should not hold Tab. Close the menu on Escape and return focus to the button that opened it. Keep aria-expanded on the button in step with the menu. A native <select> would avoid the problem entirely.
menu.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
closeMenu();
button.setAttribute("aria-expanded", "false");
button.focus();
}
});
// Delete the handler that moves focus from the last option to the first.
Retest: Open. We repeat every step above after your fix ships and mark it passed only when the steps no longer reproduce the issue.