Blog · 18 min read
Developers Need More Than Scans for Form Accessibility: H44 and H71

An accessible form gives every control a programmatic label, pairs instructions and constraints with the fields they describe, works fully from a keyboard, and reports errors in a way assistive technology can read. Each of these maps to a specific technique, including H44 for labels and aria-invalid for error states. Below, we walk through the markup patterns, a QA checklist, and how we validate forms at the code level.
TL;DR:
Use a matching label and input identifier whenever visible text exists; reserve ARIA labels for controls without a direct visible label.
When validation fails, identify the field as invalid, link a specific error message to it, and move keyboard focus to a summary of all errors.
Automated scans catch missing labels and contrast issues, while keyboard and screen reader tests expose unreachable controls and unclear group descriptions.
Keep native keyboard behavior intact; test custom controls without a mouse, and never submit automatically when focus leaves a field or a selection changes.
Table of Contents
Labeling controls correctly with the label element
The most reliable way to connect text to an input is the native <label> element with a matching id and for attribute. This technique, documented as H44, gives the control a programmatic name and lets a click or tap on the label text move focus to the field itself, a behavior people with motor disabilities depend on.
A correct pattern looks like this:
<label for="email">Email address</label>
<input type="email" id="email" name="email">
A broken version relies on visual proximity alone, a <span> sitting near the input with no for attribute, or a placeholder used as the only label. Screen readers skip visual-only text, and placeholder content disappears the moment a user starts typing, so neither substitutes for a real label.
aria-labelledby and aria-label exist for cases without a visible 1:1 label, such as a search box labeled by a nearby heading. Both work, but they come with a tradeoff: unlike the native element, aria-labelledby does not give you click-to-focus behavior, and when a control carries both a visible label and an ARIA label, many screen readers prefer the ARIA version, which can create mismatched announcements.
-
Prefer
<label for>whenever a visible, one-to-one label exists. -
Reserve
aria-labelledbyfor labels built from existing page text with no native equivalent. -
Never pair a visible label with a conflicting
aria-labelon the same control.
Grouping related fields with fieldset and legend
When several controls work together, such as a set of radio buttons or a block of checkboxes, wrapping them in <fieldset> with a <legend> gives screen reader users the context they need to understand the set as a whole. This is WCAG technique H71, and most screen readers announce the legend text alongside each individual control.
That repetition is exactly why legends should stay short. A legend that reads like a paragraph gets read out loud every time focus lands on a new radio button in the group, which turns a quick form into a frustrating one.
-
Use
<fieldset>and<legend>for radio groups, checkbox groups, and related date or address fields. -
Reach for
aria-describedbyinstead of a long legend when a group needs an extended explanation. -
Avoid nesting fieldsets inside each other, since the verbosity compounds with every level.
-
For long option lists, consider
<optgroup>inside a select, or convert the list to checkboxes if users need to pick more than one item.
Where to place instructions so people can actually use them
General instructions belong at the top of the form, before anyone starts filling anything in. Field-level instructions, like a required format for a password or a date, belong immediately next to the field they describe, not buried in a tooltip that only appears on hover.
The WAI tutorial on form instructions recommends connecting longer guidance to its field with aria-describedby, so a screen reader announces the label, then the description, right when focus lands on the input:
<label for="password">Password</label>
<input type="password" id="password" aria-describedby="pw-help">
<p id="pw-help">Minimum 8 characters, including one number.</p>
-
Keep instructional text short enough to scan in a few seconds.
-
Never hide required-field or format guidance behind a hover-only icon.
-
Use a visually hidden class for instructions meant only for assistive technology, never
display: none.
Pro Tip: If a format requirement matters enough to mention, put it in the field’s description, not just in a placeholder that vanishes on focus.
Building validation and error messages people can act on
Error handling is where accessible forms succeed or fail in practice. Section508 is direct about this: the name, role, state, and value of every form element must be programmatically determinable, and color alone can never be the only signal that a field has a problem.
A dependable pattern follows a few steps:
-
Mark the invalid field with
aria-invalid="true"so assistive technology announces its error state. -
Connect an error message to the field with
aria-describedby, pointing to an element containing plain, specific text. -
Build an error summary at the top of the form once validation runs, listing every problem as a link that jumps to its field.
-
Move keyboard focus to that summary when submission fails, so screen reader users hear it immediately.
-
Pair any error icon or red border with visible text, never color by itself.
One widely cited developer resource notes that relying only on color or icons to flag an error creates a barrier for users with low vision or color blindness, and recommends role="alert" or aria-live regions alongside an in-page error list. That single pattern, error state plus description plus a linked summary, resolves most of the common validation failures teams run into.
<input id="dob" aria-invalid="true" aria-describedby="dob-error">
<span id="dob-error" role="alert">Enter your date of birth as MM/DD/YYYY.</span>
Keeping forms usable from the keyboard alone
Every native HTML control already supports keyboard interaction correctly out of the box. Tab moves focus forward, Shift+Tab moves it back, Enter submits, and arrow keys move between radio options. The safest rule for developers is to leave that behavior alone rather than override it with custom JavaScript handlers.
When validation fails, focus should move to the error summary rather than staying where it was or jumping back to the top of the page. Since a <div> isn’t focusable by default, giving the summary container tabindex="-1" makes it programmatically reachable the moment you call .focus() on it.
One pattern to avoid entirely is submitting a form automatically when focus leaves a field or when a user changes a selection. This is a documented accessibility failure, F36, because it changes context without warning and can strand keyboard users mid-navigation.
-
Never remove or override the default Tab order without a strong, tested reason.
-
Set focus to the error summary with
tabindex="-1"plus a scripted.focus()call on failed submission. -
Avoid auto-submitting on blur, selection change, or any event the user didn’t explicitly trigger.
-
Test every custom control (comboboxes, date pickers, sliders) with keyboard only, no mouse.
Pro Tip: If you built a custom dropdown or combobox, test it the same way you’d test a native select: Tab in, arrow through options, and Enter to confirm, with no mouse at all. Our combobox accessibility testing guide walks through this in more detail.
Identifying input purpose with autocomplete and input types
Browsers and password managers can fill in a form correctly only when they know what each field is for. The autocomplete specification defines standard tokens, like name, email, street-address, and bday, that let browsers and assistive technology identify a field’s purpose reliably. This is WCAG technique H98, and it directly supports the Identify Input Purpose success criterion.
Custom or misspelled tokens break this entirely: a browser that doesn’t recognize the value simply ignores it, and autofill stops working for that field.
-
Use standard tokens like
autocomplete="email"orautocomplete="street-address"rather than inventing your own. -
Choose semantic input types,
type="email",type="tel",type="date", so mobile keyboards adapt automatically. -
Add
inputmode="numeric"for numeric-only fields like postal codes, even when the underlying type stays text.
Designing multi-page forms and time limits that don’t punish users
Long forms are easier to finish when they’re broken into logical steps with a visible progress indicator, and when overall instructions repeat on every page rather than appearing once and disappearing. The WAI tutorial on multi-page forms also recommends preserving entered data when a user navigates backward, so nobody has to retype an address because they wanted to double-check an earlier field.
Time limits deserve particular caution. A short, fixed session timeout can cut off someone using a screen reader or switch device mid-task, simply because reading and responding takes longer than a mouse-driven interaction does.
-
Break long forms into steps with a progress indicator and a descriptive page title for each step.
-
Preserve previously entered values when a user goes back, and let them skip clearly optional steps.
-
Avoid short, fixed time limits, and when a timer exists, give users a way to extend or turn it off.
-
Update the document title and announce step changes so screen reader users know where they are.
Checking whether your form is actually accessible
A quick manual pass catches most of the obvious problems before you ever open a screen reader. Click on each visible label and confirm focus lands on its input, tab through the whole form in order, and confirm every required field and error message is visible as text, not just color.
WebAIM’s guide to accessible form controls is direct about combining methods: automated scanners catch a meaningful share of structural issues, missing labels, missing for attributes, but they routinely miss context-dependent problems, like a legend that doesn’t actually describe its group or an error message that isn’t connected to its field. A manual screen reader smoke test with NVDA or VoiceOver closes that gap by confirming the label, state, and any error text are announced together, in the right order.
-
Click every label and confirm the paired input receives focus.
-
Tab through the entire form and confirm the order matches the visual layout.
-
Trigger a validation error and confirm NVDA or VoiceOver announces the field, its state, and the message.
-
Run an automated scan to catch structural issues like missing labels or low contrast.
-
Review results manually, since scanners can’t judge whether a description is actually useful.
| Check type | What it catches | What it misses |
|---|---|---|
| Automated scan | Missing labels, color contrast, missing ARIA attributes | Whether a description is meaningful or a group makes sense |
| Keyboard-only pass | Broken tab order, unreachable controls, auto-submit | Screen reader announcement quality |
| Screen reader test | Label, state, and error announcement accuracy | Large-scale regression tracking across a whole site |
How we validate forms at the code level
Running these checks by hand across every form on a growing site isn’t realistic for most teams, which is why we built our scans around the same techniques covered above. We check forms against WCAG 2.2 AA success criteria, with mappings to Section 508 and EN 301 549, so a single scan tells you where a label is missing, where a group lacks a legend, or where an error isn’t connected to its field.
Every finding we surface ties to the specific element and criterion it affects, with plain-language guidance for fixing it directly in your code rather than patching it at runtime. That distinction matters for forms especially, since a runtime overlay can’t reliably add a missing for attribute or restructure a fieldset.
-
We map each form issue to the exact WCAG, Section 508, or EN 301 549 criterion it violates.
-
We provide code-level fix guidance so remediation is permanent, not a temporary patch.
-
We run scheduled re-checks that catch regressions when a form template changes.
-
We keep dated records of scans and fixes, which supports your broader compliance documentation.
-
Our visitor-facing widget gives people display preferences like contrast and text sizing, as a complement to code fixes, never a replacement for them.
Using ARIA roles and properties beyond native HTML
Native HTML elements should always come first, since browsers and assistive technology already understand <input>, <select>, and <button> without any extra work. ARIA earns its place when you build something HTML has no native equivalent for, a combobox with live filtering, a custom multi-select, or a rich autocomplete list.
In those cases, role, aria-expanded, aria-selected, and aria-activedescendant let you expose the same name, role, state, and value information a native control would provide automatically. A custom combobox, for instance, needs role="combobox" on the input, aria-expanded toggled as the list opens and closes, and aria-activedescendant pointing to whichever option currently has visual focus. Get any one of these wrong and the control looks fine visually while announcing nothing useful to a screen reader.
aria-live regions matter for forms whenever content changes without a page reload: a character counter, a “username available” check, or a price that updates as someone adjusts quantity. Set the region to aria-live="polite" for routine updates and reserve role="alert" (which behaves as assertive) for validation failures that need immediate attention.
The rule worth keeping in mind throughout: ARIA changes what assistive technology announces, but it never changes what a browser does mechanically. Adding role="button" to a <div> doesn’t make it respond to the Enter key. You still have to write that handler yourself, which is one more reason to reach for ARIA only when native HTML genuinely can’t do the job.

Color contrast and visible focus on form elements
Form fields need enough contrast to be legible and enough visible focus feedback to show a keyboard user exactly where they are. Section508.gov’s accessible design guidance is explicit that color can never be the only way a field communicates required status or an error, icons and text need to carry that information too.
Borders, placeholder-style helper text, and disabled-state styling are common trouble spots, since designers sometimes choose a light gray that looks clean but fails contrast ratios against the background. The same applies to focus indicators: a default browser outline is often removed in custom styling and never replaced, which leaves keyboard users with no visual cue about which field is active.
A few practical habits prevent most of these problems:
-
Give every input a visible border or background change against its surrounding page, not just a subtle shadow.
-
Never remove the default focus outline without replacing it with an equally visible custom style.
-
Mark required fields and errors with text or icons in addition to any color change.
-
Check contrast on placeholder text and disabled fields too, since both are easy to overlook.
Testing this well means checking the form in its actual states, default, focused, filled, and showing an error, not just the empty version a design file usually shows.
Handling dynamic updates like live validation feedback
Forms that validate as you type or update a message without a page reload need to communicate those changes to people who aren’t looking at the screen. A sighted user notices a red border appear instantly; a screen reader user hears nothing unless the update is announced.
The WAI tutorial on form notifications recommends role="alert" or aria-live regions for this, choosing “polite” for low-urgency updates like a character count and reserving the assertive behavior of role="alert" for validation errors that need to interrupt whatever the user is doing. For error messages specifically, moving focus to a container with tabindex="-1" set guarantees the screen reader reads the new content immediately, rather than relying on a live region that some screen reader and browser combinations handle inconsistently.
One pattern worth avoiding is validating on every keystroke for complex fields like passwords. Constant interruption mid-typing is disorienting for screen reader users and often premature anyway, since the field isn’t finished yet. Validating on blur, after the user has moved to the next field, usually strikes a better balance between speed and clarity.
Making CAPTCHA and verification steps accessible
CAPTCHA remains one of the most common points where an otherwise accessible form breaks down, since many implementations depend entirely on reading distorted text or identifying objects in an image, tasks that are difficult or impossible for people with visual or cognitive disabilities.
Audio alternatives help, but only when they’re genuinely usable: clear speech, reasonable pacing, and an easy way to request a new challenge if the audio is unclear. Logic-based challenges, simple math or pattern questions, offer another route, though they still need to be presented with proper labels and instructions like any other form field.
Honeypot fields and behavioral scoring, which run invisibly in the background without requiring any user interaction, avoid the problem entirely for most visitors and deserve serious consideration as a first option. When a visible challenge is unavoidable, pairing it with multiple response modes, visual, audio, and a fallback like an accessible support contact, keeps the form usable for more people. Our guide to accessible CAPTCHA options covers these approaches with more implementation detail.
Whatever method you choose, treat it as a form field subject to the same rules as everything else on the page: a proper label, clear instructions, and an error message that explains exactly what to try next.

Designing forms for mobile and touch screens
Touch targets need real size to work reliably, a checkbox or radio button that’s technically tappable but visually tiny forces users to zoom in or tap repeatedly, which is especially difficult for anyone with limited fine motor control. A minimum touch target around 44 by 44 pixels gives most people, including those using a stylus or a finger with reduced precision, a reasonable margin for error.
Semantic input types and inputmode attributes matter even more on mobile than on desktop, since they determine which keyboard layout actually appears. A type="tel" field should bring up a numeric keypad, not a full QWERTY keyboard that forces extra taps to find each digit.
Labels and instructions need to stay visible even as the on-screen keyboard takes up half the viewport. A field description that gets pushed off-screen the moment the keyboard appears defeats its own purpose, so testing on an actual device, not just a resized browser window, catches layout problems a desktop simulation misses. Error messages and the error summary pattern described earlier apply just as directly here, though summary links need generous spacing so a shaky tap doesn’t land on the wrong one.
What teams get wrong when shipping accessible forms first
The biggest gap we see isn’t ignorance of WCAG, it’s sequencing. Teams often add ARIA attributes and error messaging before fixing the basics: real labels, a sensible tab order, visible focus. Fix the foundation first. Programmatic labels and honest validation messages solve more real problems than any amount of ARIA polish layered on top of broken markup. Keep dated records of every scan and fix, and pair automated checks with actual keyboard and screen reader testing, since neither one alone tells the whole story.
— The AccessWiser Team
Get a WCAG-mapped scan of your own forms
Reading through label associations, error patterns, and focus management is one thing, confirming your actual forms meet them is another. We scan sites against WCAG 2.2 AA success criteria, with mappings to Section 508 and EN 301 549, and flag exactly where a form field is missing a label, a group lacks a legend, or an error isn’t connected to its field.
Every finding comes with plain-language guidance for fixing it directly in your code, and scheduled re-checks catch regressions the next time a template changes, with dated records you can point to as evidence of ongoing work. Compare plans, including Starter, Basic, and Pro, and start a scan on your own forms today.
FAQ
What is an accessible form?
An accessible form is one where every control has a programmatic label, instructions and error messages are connected to their fields through attributes like aria-describedby, and the entire form can be completed using only a keyboard. It also means errors are announced to screen readers, not just shown visually.
What are the three types of accessibility?
Accessibility is commonly discussed in terms of perceivable, operable, and understandable content, which together with robust make up the four core principles behind WCAG. For forms specifically, this means content people can see or hear, controls they can operate by keyboard or touch, and instructions clear enough to follow without confusion.
How do I check if a form is accessible?
Start with a manual pass: click each label to confirm it focuses the right input, tab through the whole form, and trigger an error to see if it’s announced in text, not just color. Follow that with a screen reader smoke test using NVDA or VoiceOver, then run an automated scan to catch structural issues like missing labels, since manual and automated checks catch different problems.
How do I make Microsoft Forms accessible?
Microsoft Forms includes built-in accessibility features like keyboard navigation and screen reader support for standard question types, but custom formatting, image-based questions, and complex branching logic still need manual review. Always add descriptive question text, avoid relying on color-coded instructions, and test the finished form with a keyboard and a screen reader before sharing it widely.
Does form accessibility affect ADA compliance?
Accessible forms support broader ADA and digital accessibility compliance efforts, since forms are often the specific point where a person with a disability needs to complete a transaction or request. For a fuller look at what the law expects from websites, AccessWiser’s ADA guide covers the practical requirements in plain language.
Sources
Recommended
-
Accessible Tabs for Developers: 5 Markup Habits and When Scanners Fail
-
Ship Fixes Fast: WCAG 2.2 AA Accessibility Testing for Developers
-
7 Steps for Developers to Test and Fix Keyboard Accessibility
Articles on this blog are general information about web accessibility, not legal advice. Laws change and their application depends on your specific situation — for decisions with legal consequences, consult a qualified legal professional.
Articles on this blog are general information about web accessibility, not legal advice. Laws change and their application depends on your specific situation — for decisions with legal consequences, consult a qualified legal professional.