𝗛𝗼𝘄 𝘁𝗼 𝗪𝗶𝗿𝗲 𝗔𝗥𝗜𝗔 𝗙𝗼𝗿 𝗙𝗼𝗿𝗺 𝗘𝗿𝗿𝗼𝗿𝘀
Most forms work well for sighted users but fail for people using assistive technology. A sighted user sees a red border and an error message. A screen reader user often hears nothing.
You can fix this with two ARIA attributes and a small live region. This change takes under 50 lines of code.
Here is how you connect your errors to your inputs.
- Use aria-describedby The input needs to point to the error element. Add aria-describedby to your input and set its value to the ID of your error div.
Example:
- Input ID: email-input
- Error ID: email-error
- Code: aria-describedby="email-error"
This tells the screen reader to read the error message when the user focuses on the input. You can add multiple IDs if you have help text as well.
- Use aria-invalid This attribute tells the user that the entry is wrong. Set aria-invalid to true when an error appears. Set it to false when the error clears.
A common mistake is styling a wrapper div red but only putting aria-invalid on the input. This creates a mismatch. Ensure your visual styles and your ARIA attributes target the same element.
- Add a live region If an error appears while a user is still typing, they might miss it. Use aria-live="polite" on your error div.
- aria-live="polite" tells the screen reader to announce the error during a natural pause.
- Do not use "assertive" unless it is an emergency. Form errors are not emergencies.
- Handle async validation If you check a username or address in the background, users need to know the system is working.
- Pattern A: Use aria-busy="true" on the input while the check runs.
- Pattern B: Use a hidden live region to announce status updates like "Verifying username..."
Pattern B is more reliable across different screen readers.
Testing is mandatory. Automated tools are helpful but they cannot replace manual testing. Use NVDA on Windows or VoiceOver on macOS.
Your test checklist:
- Tab into the field. The label should announce.
- Enter an invalid value. The error should announce.
- Tab back to the field. The label should announce along with the error.
- Fix the error. The error message should clear.