I started taking form accessibility seriously after watching a user testing session where someone using a screen reader couldn't complete a contact form on a site I'd built. The label was there visually, but it wasn't connected to the input. Thirty seconds to fix, months of broken experience for real users.
Labels: Get the Basics Right
Every form input needs a visible <label> element with a for attribute matching the input's id. Don't use placeholder text as the label — once a user starts typing, the label disappears and they've lost context.
<label for="email">Email address</label>
<input type="email" id="email" name="email">Group Related Fields with fieldset and legend
Radio buttons and checkboxes that belong to a question need a <fieldset> with a <legend>. Screen readers announce the legend before each option, so users always know what question they're answering.
Error Messages That Are Actually Useful
Don't just change the border colour to red. Add an error message in text, associated with the field via aria-describedby. Tell users what went wrong and how to fix it — "Email address is required" is useful, "Invalid input" is not.
Focus States: Don't Remove Them
Keyboard users navigate forms entirely with Tab and arrow keys. If you've set outline: none on focused inputs, you've made the form unusable for keyboard navigation. Use :focus-visible to style it, but never remove it entirely.