Building Forms That Don't Make Users Want to Quit

AJ
8 min read

Why Forms Are So Hard to Get Right

Forms look simple. A few inputs, a button, done. But they're actually the hardest UI to build well. Validation, error states, loading states, accessibility, keyboard navigation, multi-step flows, responsive layout. Get any of these wrong and people leave. Here's how to get them right.

Structure First

form-structure.tsx

Validation That Helps

Bad validation yells at people. Good validation guides them:

  • Validate on blur, not on type. Don't show errors while someone is still typing.
  • Clear errors when they fix it. Remove the error as soon as the input becomes valid.
  • Say what's wrong AND how to fix it. Not "Invalid input." Instead: "Email must include @."
  • Mark required fields. Either mark required or optional. Not both. Most forms mark optional since most fields are required.
  • Use native validation when possible. type="email", required, pattern work great.
validation.tsx

Loading and Success States

submit-states.tsx

Accessibility Checklist

  • Every input has a visible <Label> linked with htmlFor
  • Error messages are linked to inputs with aria-describedby
  • Invalid inputs have aria-invalid="true"
  • Required fields are marked with aria-required="true"
  • Tab order follows visual order
  • Form can be submitted with Enter key
  • Focus moves to first error after failed submission

UX Tips

  • Single column. Multi-column forms are harder to scan. One column is almost always better.
  • Big enough inputs. Minimum height of 40px. 44px is better for touch.
  • Autofocus the first field. Save users a click.
  • Use the right input type. type="email" shows the @ keyboard on mobile. type="tel" shows the number pad.
  • Break long forms into steps. Show progress. Let people go back.
  • Save progress. If the form is long, save to localStorage so people don't lose their work.

The Short Version

  • Label every input. Use htmlFor. No exceptions.
  • Validate on blur, not on type. Clear errors when fixed.
  • Show what's wrong and how to fix it
  • Use React Hook Form + Zod for validation
  • Always show loading and success states on submit
  • Single column, big inputs, right input types
  • Break long forms into steps with saved progress

Related Articles

Your Product
Deserves a better ui