HTML Form Accessibility
Making forms usable for everyone
âŋ Why Form Accessibility Matters
Accessible forms ensure all users, including those with disabilities, can interact with your website effectively using screen readers and other assistive technologies.
<!-- Accessible form example -->
<label for="email">Email Address</label>
<input type="email" id="email" required
aria-describedby="email-help">
<div id="email-help">We'll never share your email</div>
Output:
We'll never share your email
Proper Labels
Explicit Labels
Use for attribute to connect labels
<label for="name">Name</label>
<input id="name" type="text">
Implicit Labels
Wrap input inside label
<label>
Name: <input type="text">
</label>
aria-label
For inputs without visible labels
<input type="search"
aria-label="Search products">
aria-labelledby
Reference existing text as label
<h2 id="billing">Billing</h2>
<input aria-labelledby="billing">
đ Fieldsets and Legends
Group related form controls for better organization:
<fieldset>
<legend>Contact Information</legend>
<label for="fname">First Name</label>
<input type="text" id="fname" required>
<label for="lname">Last Name</label>
<input type="text" id="lname" required>
<label for="phone">Phone</label>
<input type="tel" id="phone">
</fieldset>
Output:
âšī¸ Descriptions and Help Text
Provide additional context with aria-describedby:
<label for="password">Password</label>
<input type="password" id="password"
aria-describedby="pwd-help" required>
<div id="pwd-help">
Must be at least 8 characters with numbers and letters
</div>
<label for="username">Username</label>
<input type="text" id="username"
aria-describedby="user-help">
<div id="user-help">
Choose a unique username (3-20 characters)
</div>
Output:
Must be at least 8 characters with numbers and letters
Choose a unique username (3-20 characters)
â ī¸ Error Messages
Make error messages accessible and clear:
<label for="email-err">Email</label>
<input type="email" id="email-err"
aria-describedby="email-error"
aria-invalid="true" required>
<div id="email-error" role="alert">
Please enter a valid email address
</div>
<!-- Success state -->
<label for="email-ok">Email</label>
<input type="email" id="email-ok"
aria-describedby="email-success"
aria-invalid="false">
<div id="email-success">
â Valid email address
</div>
Output:
Please enter a valid email address
â Valid email address
â¨ī¸ Keyboard Navigation
Ensure forms work with keyboard-only navigation:
<!-- Proper tab order -->
<input type="text" tabindex="1">
<input type="email" tabindex="2">
<button type="submit" tabindex="3">Submit</button>
<!-- Skip to main content -->
<a href="#main-form" class="skip-link">Skip to form</a>
<form id="main-form">
<!-- Form content -->
</form>