Approach (brief)
I’d design each step as a semantic section with clear labels, inline error text linked to fields, and predictable keyboard/focus flow so screen readers announce validation state and users can complete the form without a mouse.
Structure & semantics
- Use native form controls, wrap related inputs in <fieldset> + <legend> for grouped context.
- Each input has a visible <label for="id"> and also label text programmatically associated (no placeholder-as-label).
- Inline error text exists in a <div id="err-email" class="error" role="alert" aria-live="assertive">Email is required</div> and is referenced from the input with aria-describedby="err-email" when present.
- Set aria-invalid="true" on invalid inputs.
Focus order & keyboard-only operation
- Linear DOM order: step header → fields → next/back buttons. Tab order follows DOM.
- On Next, validate client-side. If errors:
- Move focus to a single, keyboard-focusable error summary at top of the step (tabindex="-1") and set focus() so screen readers land on it.
- Error summary lists links that focus() the corresponding invalid input when activated.
- If one error only, focus the invalid control directly to let the user correct immediately.
Announcing step errors to AT
- Use an error summary container with role="alert" or aria-live="assertive" that updates with the count of errors (e.g., "2 fields require attention in Step 2"). Make it focusable (tabindex="-1") and programmatically focus it after update.
- Inline messages also use aria-live="polite"/role="status" for ongoing changes (e.g., server-side validation returning).
- For progressive disclosure (conditional fields), add aria-hidden appropriately when hidden and remove aria-describedby/aria-invalid when field is removed.
Progress & step status
- Use a progress indicator with aria-current="step" or a progress bar with role="progressbar" and aria-valuenow/aria-valuemin/aria-valuemax for screen-reader feedback.
Developer handoff notes
- Provide IDs for error messages, CSS states for focus/invalid, sample scripts: set aria-invalid, update aria-describedby, focus error summary.
- Test with VoiceOver, NVDA, and keyboard-only flows; include example flows in the spec.
This ensures semantic labels, clear inline linking, deterministic focus behavior, and explicit announcements to assistive tech across multi-step navigation.