Accessible Form Components
Label every input, associate errors with aria-describedby, and provide clear required field indicators and descriptive error messages.
Why Accessible Forms Matter
Forms are one of the most critical interaction points in web applications — used for login, checkout, search, and data entry. Inaccessible forms exclude users who rely on screen readers, keyboard navigation, or voice control. Common failures include unlabeled inputs, errors that only appear visually, required field indicators that screen readers cannot detect, and focus that does not move to errors after submission. Tailwind provides all the utilities needed to build forms that work for everyone.
Labeling Every Input
Every form input must have a programmatic label — not just visual placeholder text. Placeholders disappear when the user types and are not reliably read by all screen readers. Use a <label> element with a for attribute matching the input's id. This creates a binding: clicking the label focuses the input, and screen readers announce the label when the input is focused. Never remove visible labels for design reasons — they are accessibility requirements.
<!-- GOOD: visible label with for/id binding -->
<div class='flex flex-col gap-1'>
<label for='email' class='text-sm font-medium text-gray-700'>
Email address
</label>
<input
id='email'
type='email'
name='email'
placeholder='you@example.com'
class='rounded-lg border border-gray-300 px-3 py-2 text-sm
focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500'
/>
</div>
<!-- BAD: placeholder-only labeling -->
<input type='email' placeholder='Email address'
class='rounded-lg border border-gray-300 px-3 py-2' />
{/* Placeholder disappears on input — user forgets what the field is for */}