Accessible Forms: WCAG Inputs, Labels, and Errors
Missing labels, broken error handling, and inaccessible inputs block real users from completing forms. Learn how to fix common WCAG form violations with practical code examples.
Forms are the workhorses of the web. Every sign-up flow, checkout page, contact form, and search bar relies on form elements to collect input from users. When those forms aren't built with accessibility in mind, entire groups of people are shut out from completing essential tasks: making purchases, creating accounts, requesting support, or even logging in.
The good news is that accessible forms aren't complicated. Most of the work comes down to using the right HTML elements, connecting them properly, and communicating clearly when something goes wrong. This guide walks through each principle with practical steps you can apply immediately.
Every Input Needs a Visible, Associated Label
This is the most fundamental rule of accessible forms, and the one most frequently broken. A screen reader user who lands on a text field needs to hear what information is expected. Without a programmatically associated label, they hear nothing - or worse, they hear the wrong thing.
The most reliable way to associate a label with an input is the HTML <label> element with a for attribute that matches the input's id. This creates an explicit connection that every assistive technology understands. It also makes the label clickable, which increases the target area for mouse and touch users - a usability win for everyone.
Placeholder text is not a substitute for a label. Placeholders disappear as soon as the user begins typing, which creates problems for people with short-term memory difficulties and makes it impossible to verify what a field is asking for after you've started entering data. Use placeholders only for supplementary hints, never as the primary label.
Group Related Fields with Fieldset and Legend
When a form contains groups of related inputs - such as a set of radio buttons for selecting a shipping method, or a section of fields for a billing address - those groups need a programmatic relationship that assistive technology can convey.
The <fieldset> element wraps the group, and the <legend> element provides the group's label. When a screen reader user moves into a fieldset, they hear the legend announced along with each individual input's label. Without this structure, a set of radio buttons labeled "Standard," "Express," and "Overnight" gives no indication that these are shipping options.
This pattern is especially important for radio button groups and checkbox groups, but it's equally useful for any logical section of a longer form - personal information, payment details, preferences, and so on.
Use the Correct Input Types
HTML provides specific input types for different kinds of data: email, tel, url, number, date, password, and more. Using the correct type does several important things for accessibility and usability simultaneously.
On mobile devices, the correct input type triggers the appropriate keyboard - a number pad for phone numbers, an email-optimized keyboard with the @ symbol readily available, a URL keyboard with .com shortcuts. For users with motor impairments who find typing difficult, this reduces the number of keystrokes needed.
Input types also provide built-in validation behavior. A field with type="email" will flag entries that don't contain an @ symbol, giving users immediate feedback without requiring custom JavaScript validation.
Beyond type attributes, use the autocomplete attribute to tell browsers what kind of data a field expects. Values like autocomplete="given-name", autocomplete="street-address", and autocomplete="cc-number" allow browsers and password managers to fill in information automatically. WCAG 2.1 Success Criterion 1.3.5 specifically requires this for fields that collect common personal information, because autofill reduces the cognitive and motor effort required to complete a form.
Communicate Errors Clearly and Accessibly
Form validation is where many otherwise accessible forms fall apart. Two WCAG criteria set the bar. 3.3.1 Error Identification (Level A) says that when an error is detected automatically, "the item that is in error is identified and the error is described to the user in text." 3.3.3 Error Suggestion (Level AA) adds that when you know how to fix the error, you tell the user, unless that would jeopardize the security or purpose of the content.
Why a red border alone fails
A red border around an invalid field is not enough on its own. Color cannot be the only way you convey information, per WCAG Success Criterion 1.4.1 Use of Color, and 3.3.1 asks for the error in text. Users who are colorblind, using a monochrome display, or using a screen reader will miss a border entirely. The Understanding document for 3.3.1 says color or an icon is fine in addition to the text description. Our color contrast checker flags the related contrast failures.
The message itself should say what went wrong and how to fix it: "Enter an email address in the format [email protected]" is far more useful than "Invalid input." That second half is what 3.3.3 asks for.
What aria-invalid does, and when to set it
aria-invalid tells assistive technology that a field's current value failed validation. A screen reader announces the field as "invalid entry" or similar when the user reaches it. The WAI-ARIA 1.2 specification allows four values: true, false (the default), grammar and spelling. For form validation you only need true, and setting false is the same as leaving the attribute off.
The timing matters more than the attribute:
- Set it only after a failed validation attempt, on submit or when the user leaves a field they have filled in. W3C technique ARIA21 says it "should not be set to true before input validation is performed."
-
Never on an untouched form. The ARIA specification says authors should not set
aria-invalidon required fields "simply because the user has not yet entered data." A form that loads with every required field announced as invalid tells screen reader users they have made mistakes they have not made. -
Remove it when the field is corrected. Re-validate on input or blur after the first error, and drop the attribute (or set it to
false) as soon as the value passes. A field that stays "invalid" after it is fixed is as misleading as a missing error.
<!-- Broken: invalid before the user has typed anything, error only in color -->
<label for="email">Email</label>
<input id="email" type="email" required aria-invalid="true" class="border-red">
<!-- Fixed: invalid only after a failed submit, message in text and linked -->
<label for="email">Email</label>
<input id="email" type="email" required autocomplete="email"
aria-invalid="true" aria-describedby="email-error">
<p id="email-error" class="field-error">
Enter an email address in the format [email protected]
</p>
aria-describedby or aria-errormessage?
Both point a field at its error text. They behave differently:
| Attribute | What it does | When to use it |
|---|---|---|
aria-describedby |
Adds the referenced text to the field's description, which screen readers read when the field gets focus. It works whether or not the field is invalid. | The dependable default. It is the pattern in W3C technique ARIA21's examples. Point it at the hint and the error together if both exist: aria-describedby="email-hint email-error". |
aria-errormessage |
Marks the referenced text specifically as the error. The ARIA specification says it only applies while aria-invalid is true, and the message must not be hidden while it applies. |
Only as an addition. Screen reader support has lagged behind aria-describedby, so check current results (for example on a11ysupport.io) and test with the screen readers your users have before relying on it alone. |
If you are not sure, use aria-describedby. It is the safe choice today.
Add an error summary for longer forms
When a submission fails, move focus to a summary of all errors at the top of the form, so keyboard and screen reader users are not left wondering what happened. Each item links to the field it describes, and each field still carries its own inline message. W3C lists providing text descriptions of each error as technique G139.
<!-- Fixed: summary receives focus after a failed submit -->
<div class="error-summary" tabindex="-1" id="error-summary">
<h2>There are 2 problems with your answers</h2>
<ul>
<li><a href="#email">Enter an email address in the format [email protected]</a></li>
<li><a href="#postcode">Enter a postcode, like SW1A 1AA</a></li>
</ul>
</div>
// On a failed submit: mark each invalid field, then focus the summary
form.addEventListener("submit", (event) => {
const invalid = [...form.elements].filter((el) => el.willValidate && !el.checkValidity());
if (invalid.length === 0) return;
event.preventDefault();
invalid.forEach((el) => el.setAttribute("aria-invalid", "true"));
document.getElementById("error-summary").focus();
});
// Once corrected, clear the state so the field stops announcing as invalid
form.addEventListener("input", (event) => {
const el = event.target;
if (el.getAttribute("aria-invalid") === "true" && el.checkValidity()) {
el.removeAttribute("aria-invalid");
}
});
The script is a sketch: in a real form you also write and show the matching message text, and add novalidate to the form so the browser's own bubbles do not appear on top of yours. The form label checker finds fields with no accessible name, and a free accessibility scan checks the labels and ARIA attributes on the whole page. Whether each error message is clear and helpful still needs a person, because 3.3.1 and 3.3.3 cannot be judged by a tool.
Make Forms Fully Keyboard Operable
Every form element must be reachable and operable using only a keyboard. Native HTML form elements - <input>, <select>, <textarea>, <button> - are keyboard accessible by default. Problems arise when developers build custom components using <div> or <span> elements styled to look like form controls but lacking any keyboard support.
If you must build a custom form component, ensure it can receive focus (using tabindex="0"), responds to expected keyboard interactions (Enter and Space to activate buttons, arrow keys to navigate options in a custom dropdown), and has the appropriate ARIA role and state attributes. But in almost every case, starting with the native HTML element and styling it is simpler, more robust, and more accessible.
Tab order should follow the visual order of the form. Users expect to move through fields from top to bottom and left to right in left-to-right languages. Avoid using tabindex values greater than 0, which override the natural document order and create confusing navigation sequences.
Focus indicators must be visible. The default browser focus outline should never be removed with outline: none unless a custom focus style of equal or greater visibility replaces it. WCAG 2.2 Success Criterion 2.4.13 Focus Appearance sets a measurable bar for the contrast and size of focus indicators, though at Level AAA rather than AA (WCAG 2.2). The AA requirement is 2.4.7 Focus Visible, and our keyboard and focus checker covers it.
Provide Clear Instructions and Help Text
Don't make users guess what format you expect or what rules apply to their input. If a password must contain at least eight characters, a number, and a special character, state that before the input - not as an error message after they've already submitted the form.
Instructions that appear before the form and help text associated with specific fields should be connected to those fields using aria-describedby. This ensures screen reader users hear the guidance when they focus the relevant input, not just visually sighted users who happen to read the surrounding text.
For required fields, don't rely solely on a red asterisk - it's a visual convention that not everyone understands, and it conveys no information to screen reader users unless handled properly. Use the HTML required attribute, which both triggers native browser validation and communicates the required state to assistive technology. If you also use an asterisk for visual consistency, include a text explanation at the top of the form that the asterisk indicates a required field.
Design for Touch and Motor Accessibility
Form controls need to be large enough to activate accurately. WCAG 2.2 Success Criterion 2.5.8 Target Size (Minimum), Level AA, requires interactive targets to be at least 24 by 24 CSS pixels (WCAG 2.2), and our target size checker measures them. For form elements - especially checkboxes, radio buttons, and small buttons - this often means adding padding or increasing the overall clickable area.
Spacing between form elements matters too. If interactive targets are packed tightly together, users with motor impairments risk activating the wrong control. Provide adequate spacing between fields, between radio buttons or checkboxes within a group, and between action buttons.
Avoid interactions that require precise gestures or complex mouse movements. Drag-and-drop interfaces for reordering form items should always have a keyboard-accessible alternative. Multi-step interactions where a slip means starting over create unnecessary barriers for users with tremors or limited dexterity.
Handle Dynamic Forms Accessibly
Modern forms often change dynamically - showing or hiding fields based on a previous selection, loading additional options via an API, or displaying real-time validation results as the user types. These dynamic updates need to be communicated to assistive technology users who can't see the visual changes.
Use ARIA live regions to announce important dynamic changes. An aria-live="polite" region will wait for the screen reader to finish its current announcement before conveying the new information - appropriate for non-urgent updates like character count feedback. An aria-live="assertive" region interrupts the current announcement - appropriate for critical messages like session timeout warnings.
When new fields appear in a form based on a user's selection, manage focus thoughtfully. If a user selects "Other" from a dropdown and a new text field appears for them to specify, either move focus to that new field or ensure the user can find it naturally by continuing to tab forward.
Avoid automatically submitting forms when a user makes a selection or changes a value. This is disorienting for keyboard and screen reader users who may not realize the form has been submitted. Per WCAG Success Criterion 3.2.2, changing a form control's value should not automatically cause a change of context unless the user has been advised in advance.
Test Your Forms with Real Assistive Technology
Start with the keyboard: our step by step guide to testing keyboard accessibility by hand covers the pass to run before you open a screen reader.
Automated accessibility scanners are valuable for catching structural issues like missing labels and invalid ARIA attributes, but they can't tell you whether a form actually works well for someone using a screen reader or navigating by keyboard alone.
Test your forms manually by completing them using only a keyboard. Tab through every field, activate every button, trigger and read every error message. Then test with a screen reader - VoiceOver on macOS, NVDA on Windows, or TalkBack on Android. Listen to how each field is announced, whether error messages are conveyed, and whether the overall flow makes sense without visual context.
Testing with real assistive technology reveals usability issues that no automated tool can detect: confusing label wording, awkward tab sequences, error messages that make sense visually but are meaningless when heard out of context, and dynamic updates that happen silently.
An Accessible Form Checklist
To summarize the key principles, here is a reference checklist you can use when building or reviewing forms:
Every input has a visible, programmatically associated label using the <label> element. Placeholder text is not used as a replacement for labels. Related inputs are grouped using <fieldset> and <legend>. Correct input types are used for the data being collected. The autocomplete attribute is set for fields collecting personal information. Error messages are visible, descriptive, and associated with their fields via aria-describedby. Errors don't rely on color alone to communicate problems. Focus moves to the error summary or first invalid field after a failed submission. All form controls are reachable and operable by keyboard. Focus indicators are clearly visible. Tab order follows the visual layout. Required fields use the HTML required attribute. Instructions and help text are provided before or alongside inputs. Touch targets are at least 24 by 24 CSS pixels with adequate spacing. Dynamic form changes are communicated via ARIA live regions. Forms don't auto-submit on value changes without advance notice.
Start Building Better Forms Today
Accessible forms aren't just a compliance requirement, they're better forms for everyone. Clearer labels, helpful error messages, logical structure, and keyboard operability make forms easier to complete for all users, not just those using assistive technology.
Our form labels checker and our ten-minute form accessibility audit are the fastest way to audit what you already have. If you're unsure where your current forms stand, AccessGuard can scan your site and flag form-related accessibility issues: missing labels, empty buttons, inputs without associated text, and more. It gives your team the specific, actionable guidance needed to fix each issue.
Run a free accessibility scan today and make your forms work for every user who needs them. Automated checks find many real problems, but they cannot confirm that a form conforms to WCAG: that stays a human judgement.