What we cover
Give me the TL;DR

An accessible online form is one that allows every user, including those using assistive technologies, to complete each step independently through proper labeling, error handling, keyboard navigation, and WCAG-compliant interaction patterns.

Forms are where government digital accessibility fails most visibly and most consequentially.

Not the homepage. Not the navigation. Not the color palette. The form.

The permit application a resident cannot submit because the date picker traps keyboard focus. The tax payment portal where error messages appear visually but fire no screen reader announcement. The business license renewal where required fields are marked with a red asterisk that disappears when the form is in an error state. The public records request form with an unlabeled upload field that announces "edit text" to every screen reader user who tabs to it.

These are not edge cases. They are the default state of most government online forms built without accessibility as a design requirement. And unlike a contrast failure on a low-traffic page, an inaccessible form directly prevents a resident from completing a government service transaction. That is the category of barrier ADA Title II enforcement weighs most heavily.

The good news is that accessible forms are not significantly harder to build than inaccessible ones when accessibility is built in from the start. The bad news is that retrofitting accessibility into a form that was built without it is expensive, often incomplete, and frequently produces a form that passes automated testing while still failing real users.

This guide covers every element of accessible form design and development — labels, error handling, keyboard navigation, screen reader compatibility, multi-step flows, timeout behavior, and everything in between. It is written for the web teams and developers who build government forms and for the IT directors and project managers who need to know what to require.

 

TLDR: Accessible Online Form Checklist

  • Every field has a visible, programmatic label
  • Required fields use text, not color alone
  • Errors are announced and explain how to fix them
  • Tab order follows logical form flow
  • No keyboard traps exist
  • Custom components are keyboard accessible
  • Multi-step forms manage focus correctly
  • Session timeouts provide accessible warnings
  • File uploads provide accessible feedback

 

The Core Principle of Accessible Forms: Every User Must Be Able to Complete Every Step

Before getting into specific requirements, the governing principle of accessible form design is worth stating clearly.

Every user who is eligible to use a government online service must be able to complete that service independently using whatever input method they rely on. This includes users who navigate by keyboard only. Users who rely on screen readers. Users who use voice control software. Users who rely on switch access devices. Users who have cognitive disabilities that affect their ability to process complex information or recover from errors.

The accessible form does not provide a degraded experience for these users. It provides the same experience. The information they need to complete the form is equally available. The errors they make are equally recoverable. The confirmation they receive is equally informative. The time they need is equally accommodated.

Every specific requirement in this guide is a consequence of that principle applied to a specific form element or interaction.

 

Part 1: Form Labels — The Foundation of Every Accessible Form

Labels are the most important accessibility element in any form. They are the mechanism by which a screen reader user knows what a field is asking for. Without a correctly implemented label, a screen reader user focusing on a form field hears "edit text" — or worse, the field is entirely invisible to their screen reader — and has no way to know what information is being requested.

The Three Label Rules

Rule 1: Every field must have a label.

Every input element — text fields, email fields, phone number fields, date fields, select dropdowns, checkboxes, radio buttons, file uploads, textareas — must have a label. There are no exceptions.

Rule 2: The label must be programmatically associated with its field.

A label that appears visually near a field but is not programmatically connected to it does not exist for a screen reader user. Programmatic association means one of the following implementations:

The <label> element with a for attribute that matches the id of its input:

<label for="first-name">First name <span class="required">(required)</span></label>

<input type="text" id="first-name" name="first-name" required aria-required="true">

The input nested inside its label element:

<label>

  First name <span class="required">(required)</span>

  <input type="text" name="first-name" required aria-required="true">

</label>

The aria-labelledby attribute referencing the ID of a visible text element when the standard <label> approach is not feasible:

<span id="first-name-label">First name (required)</span>

<input type="text" aria-labelledby="first-name-label" name="first-name">

The aria-label attribute for fields where a visible label is not present and no visible text can be referenced — this should be used sparingly as it creates a label visible only to assistive technology:

<input type="search" aria-label="Search permit applications" name="search">

Rule 3: Labels must be visible and persistent.

Placeholder text is not a label. Placeholder text disappears when a user starts typing, leaving the field unlabeled at the exact moment the user is filling it in. Placeholder text can be used as supplementary guidance — "e.g., 555-555-5555" — but never as the sole label for a field.

Floating labels that animate from inside the field to above it when the field is focused are also not reliable substitutes for static visible labels. They are frequently implemented in ways that break screen reader label associations and create confusion for users with cognitive disabilities who may not perceive the animation.

Keep labels visible and static, positioned consistently above their fields (top-aligned labels work best for readability and zoom compatibility), and always present regardless of field state.

 

Part 2: Required Fields — Indicating Them Correctly

Required field indication is one of the most consistently wrong form elements in government websites.

What Does Not Work

A red asterisk as the sole required field indicator fails WCAG for two reasons. First, it relies on color alone to convey meaning (the asterisk's red color). Second, the convention of "asterisk means required" is not universally understood, and the meaning is typically explained only in a note at the top or bottom of the form that many users miss.

A red border on submitted-but-empty required fields that appears only in the error state fails for the same reasons — color alone, and the information arrives too late.

What Works

Visible text that does not rely on color. The clearest approach is adding the word "required" or the abbreviation "(required)" to the label of every required field:

<label for="phone">Phone number (required)</label>

<input type="tel" id="phone" name="phone" required aria-required="true">

If most fields in a form are required and you want to indicate the exceptions rather than the rule, marking optional fields with "(optional)" and explaining this convention at the top of the form is acceptable:

<p>All fields are required unless marked (optional).</p>

Programmatic required indication. Add both the HTML required attribute and aria-required="true" to required fields. The required attribute triggers browser-native required field validation. aria-required="true" communicates the required state to assistive technologies that may not fully process the HTML required attribute.

An asterisk used as a supplementary indicator — not the sole indicator. If your design uses an asterisk, it must be accompanied by a text explanation of its meaning and the required state must also be communicated in the programmatic label. The asterisk alone is never sufficient.

 

Part 3: Error Handling — The Most Critical Accessibility Element

Error handling is where most government forms completely fail accessibility — and where the consequences are most severe. An error state that is not accessible to screen reader users means a user makes a mistake, submits the form, and receives no indication that anything went wrong. They sit on what appears to be a processing screen, unaware that their application was not submitted.

Accessible error handling requires that three things happen when a form submission fails:

1. The Error Is Announced to Assistive Technology

When a form is submitted with errors, the focus must move to an accessible error summary — a list of all errors at the top of the form, or to the first errored field — and that summary or field must be announced by screen readers.

The most reliable pattern for government forms with multiple potential errors is an error summary:

<div role="alert" aria-live="assertive" id="error-summary" tabindex="-1">

  <h2>There are 2 errors in your form</h2>

  <ul>

    <li><a href="#phone">Phone number: Please enter a valid 10-digit phone number</a></li>

    <li><a href="#email">Email address: This field is required</a></li>

  </ul>

</div>

The role="alert" causes the content to be announced immediately by screen readers when it appears. The aria-live="assertive" reinforces this for dynamic content updates. The tabindex="-1" allows focus to be moved to the summary programmatically. The links inside the summary jump directly to each errored field, allowing keyboard and screen reader users to navigate directly to what needs to be fixed.

When the form is submitted with errors, JavaScript should move focus to the error summary with errorSummary.focus(). This is the moment that triggers the screen reader announcement.

2. The Error Message Identifies What Failed and How to Fix It

Accessible error messages answer two questions: which field failed, and what the correct format or value is.

Inaccessible error messages:

  • "Error" (identifies nothing)
  • "Invalid input" (identifies nothing)
  • "Please correct the highlighted fields" (relies on visual color)
  • "Required" (identifies the problem but not the field when used generically)

Accessible error messages:

  • "Phone number: Please enter a valid 10-digit US phone number in the format 555-555-5555"
  • "Date of birth: Please enter a date in MM/DD/YYYY format"
  • "Email address: This field is required — please enter your email address"
  • "File upload: The file you selected exceeds the 10MB maximum file size — please select a smaller file"

The message identifies the field by name, describes the problem, and specifies what the correct input is. It is specific enough that a user can correct the error without guessing.

3. The Error Message Is Associated With Its Field

The error message for each individual field must be programmatically associated with that field so that when a screen reader user focuses on the field, both the label and the error message are announced.

<div class="form-group error">

  <label for="phone">Phone number (required)</label>

  <span id="phone-error" class="error-message" role="alert">

    Please enter a valid 10-digit phone number in the format 555-555-5555

  </span>

  <input type="tel" id="phone" name="phone" required aria-required="true"

    aria-describedby="phone-error phone-hint" aria-invalid="true">

</div>

The aria-describedby attribute references the error message ID, causing the error message to be read after the label when focus lands on the field. The aria-invalid="true" communicates to assistive technology that the field is in an error state.

 

Part 4: Keyboard Navigation — Every Action Must Be Keyboard Accessible

Every action a user can take with a mouse in a form must be equally available using only a keyboard. This is the operability requirement that government forms most commonly fail.

Tab Order

The tab order through a form — the sequence in which focus moves when a user presses Tab — must follow the visual and logical order of the form. For a standard top-to-bottom form layout, this means:

Focus moves from the first field to the second field to the third, in the same order a sighted user would visually scan the form. Focus does not jump between unrelated sections. Focus does not skip fields. Focus does not move backwards unexpectedly.

Test the tab order by putting your mouse down and tabbing through the entire form. If focus moves in a confusing or illogical sequence at any point, the tab order needs to be corrected — either by reordering elements in the DOM or, in rare cases, by using tabindex attributes.

Do not use positive tabindex values (tabindex="1", tabindex="2") to control tab order. These are a maintenance nightmare and almost always produce worse tab behavior than fixing the underlying DOM order.

Keyboard Operability of Custom Components

Standard HTML form elements — text inputs, checkboxes, radio buttons, select dropdowns, textareas — are keyboard accessible by default. The accessibility failures in keyboard navigation almost always occur in custom form components built with non-native HTML elements.

Custom dropdown selects: If you are building a custom dropdown that replaces the native <select> element — for visual design reasons, for multi-select functionality, or for complex option displays — it must implement the ARIA combobox or listbox pattern correctly. This includes keyboard interaction: Down arrow to open and navigate options, Up arrow to navigate backwards, Enter to select, Escape to close without selecting, Home to jump to the first option, End to jump to the last option.

Date pickers: The date picker is the single most consistently inaccessible form component in government websites. A custom date picker must implement full keyboard navigation of the calendar grid (arrow keys to navigate days, Page Up/Down to navigate months, Home/End to navigate to the start/end of a week), must announce the current date and selected date to screen readers, and must allow direct text entry as an alternative to calendar interaction. If you cannot build a fully accessible custom date picker, use a text input with clear format instructions: <input type="text" placeholder="MM/DD/YYYY">.

File upload components: Native <input type="file"> elements are keyboard accessible. Custom file upload components that replace or overlay the native input frequently break keyboard accessibility. If you are using a custom file upload interface, test it specifically — can the user open the file browser using keyboard only? Can they navigate the file browser and select a file using keyboard only? Does the selected file name appear in a way that is announced to screen readers?

Custom checkboxes and radio buttons: Styled checkboxes and radio buttons that replace native form elements must preserve the native keyboard behavior (Space to check/uncheck checkboxes, arrow keys to navigate and select within radio groups) and must communicate their state to assistive technology.

Keyboard Traps

A keyboard trap occurs when focus enters a component and cannot be exited using keyboard commands. In a form context, keyboard traps most commonly occur in:

Custom dropdown menus that capture Tab key presses to navigate options and never release focus back to the page.

Modal dialogs triggered by form interactions (confirmation modals, help modals) that do not allow Escape to close and return focus to the triggering element.

Date picker calendar components that trap focus inside the calendar and do not provide a keyboard path to close the calendar and return to the date input field.

Test for keyboard traps by tabbing through the form and attempting to exit every interactive component using both Tab (move forward) and Shift+Tab (move backward) and Escape (close). If you find yourself stuck in a component with no keyboard exit, that is a trap.

 

Part 5: Multi-Step Forms and Progress Indicators

Many government service forms span multiple steps — collecting different categories of information across several screens with a progress indicator showing the user's position in the flow.

Multi-step forms require specific accessibility considerations at each step boundary.

Progress Indicators

Progress indicators must communicate current position to assistive technology, not just to sighted users. A visual progress bar with step labels is not accessible unless the current step is also communicated programmatically.

<nav aria-label="Application progress">

  <ol>

    <li aria-current="step">

      <span class="visually-hidden">Current step: </span>Personal information

    </li>

    <li>Property details</li>

    <li>Supporting documents</li>

    <li>Review and submit</li>

  </ol>

</nav>

The aria-current="step" attribute communicates the current step to screen readers. The visually hidden "Current step:" prefix provides additional context. The <nav> with a descriptive aria-label identifies the element as navigation so screen reader users can find it using navigation landmarks.

Focus Management Between Steps

When a user advances to the next step, focus must be managed deliberately. Leaving focus at its last position on the previous step — which may now be below or outside the new step's content — disorients keyboard and screen reader users.

When a new step loads, move focus to the step heading or to the top of the new step's content:

// After loading new step content

const stepHeading = document.querySelector('#step-heading');

stepHeading.setAttribute('tabindex', '-1');

stepHeading.focus();

This ensures that screen reader users hear the new step's content announced and that keyboard users begin tabbing from a logical starting point.

Validation at Step Boundaries

Validate required fields at each step boundary before allowing the user to advance. Do not allow users to reach step 4 of a 6-step form only to discover that required information from step 2 was not saved correctly.

When validation fails at a step boundary, apply the same error handling pattern as single-page forms — an error summary that is announced by screen readers, with focus moved to the summary, and individual error messages associated with each errored field.

 

Part 6: Session Timeouts — A Frequently Overlooked Barrier

Government service forms frequently include session timeouts for security reasons. A resident fills out a complex permit application, gets interrupted, returns 15 minutes later, and finds the session has expired and all their entered data is gone.

For sighted users, this is frustrating. For screen reader users who may type more slowly due to their navigation method, and for users with motor disabilities who may need more time to complete forms, session timeouts without accessible warnings can make complex government forms effectively impossible to complete.

WCAG Requirements for Session Timeouts

WCAG 2.1 Success Criterion 2.2.1 requires that any time limit can be turned off, adjusted, or extended. For government service forms with authentication sessions, the typical implementation is a warning dialog before the session expires.

The warning dialog must be keyboard accessible and must be announced to screen readers. A dialog that appears visually but fires no screen reader announcement leaves screen reader users with an expired session and no way to know why.

<div role="alertdialog" aria-modal="true" aria-labelledby="timeout-title" 

     aria-describedby="timeout-message" id="timeout-dialog">

  <h2 id="timeout-title">Your session is about to expire</h2>

  <p id="timeout-message">Your session will expire in 2 minutes due to inactivity. 

     Would you like to continue?</p>

  <button id="extend-session">Yes, continue my session</button>

  <button id="end-session">No, end my session</button>

</div>

When the timeout warning appears, move focus to the dialog. The role="alertdialog" causes the content to be announced immediately by screen readers. The user can then respond using keyboard.

The "continue" action must be operable by keyboard. The session extension must work reliably — not require the user to quickly click a button that disappears, but provide sufficient time to respond.

 

Part 7: File Upload Accessibility

File upload fields appear in a wide range of government forms — permit applications requiring site plans, license applications requiring documentation, public records requests. They are one of the more complex form elements to make accessible.

Native File Input

The native <input type="file"> element is keyboard accessible by default. When activated with Enter or Space, it opens the operating system file browser, which is itself navigable by keyboard. Use native file inputs wherever possible.

Label native file inputs like any other input — a visible, programmatically associated label that clearly describes what file is expected:

<label for="site-plan">Upload site plan (PDF, max 10MB, required)</label>

<input type="file" id="site-plan" name="site-plan" accept=".pdf" required aria-required="true">

Custom File Upload Interfaces

If a custom file upload interface is used — a drag-and-drop zone, a visually styled upload button that overlays the native input — it must preserve keyboard accessibility.

The most common pattern is a visible styled button that is actually a <label> for a visually hidden native file input:

<label for="site-plan-upload" class="custom-upload-button">

  Choose file

</label>

<input type="file" id="site-plan-upload" class="visually-hidden" accept=".pdf">

This pattern preserves keyboard accessibility because the <label> receives focus and activates the hidden file input when pressed. The selected file name should appear in an adjacent element that is announced to screen readers.

File Upload Feedback

After a file is selected or uploaded, provide accessible feedback. The filename should appear in a visible, readable element adjacent to the upload field. If the file is being processed or validated (checking file size, format, virus scanning), a status update should be announced to screen readers using an aria-live region.

If the file fails validation — wrong format, too large, upload error — apply the same error handling pattern as any other form field error: an error message associated with the field via aria-describedby, with aria-invalid="true" on the field.

 

Part 8: Testing Your Form for Accessibility

Building to these requirements eliminates most form accessibility failures. Testing verifies that the implementation matches the intention.

The Four-Test Protocol

Run these four tests on every government form before it goes live — and after any significant change to the form.

Test 1: Keyboard-only completion. Put your mouse away. Complete the entire form from beginning to submitted confirmation using only Tab, Shift+Tab, Enter, Space, and arrow keys. Confirm that every field is reachable, every dropdown and date picker is operable, every error state is navigable, and the form can be submitted successfully.

Test 2: Screen reader testing. Test with NVDA + Chrome on Windows and VoiceOver + Safari on macOS. Focus on each field and confirm the label is announced correctly. Submit the form with intentional errors and confirm errors are announced, error messages are read with field labels, and the focus moves to the error summary. Submit successfully and confirm the confirmation is announced.

Test 3: Automated scan. Run axe DevTools on the completed form. Address every violation. Treat warnings as issues requiring review.

Test 4: Zoom test. Test the form at 200% browser zoom. Confirm that all labels remain visible and associated with their fields, that error messages do not overlap content, and that the form remains operable at increased zoom levels. This is the WCAG 1.4.4 Resize Text requirement in practice.

 

The Form Accessibility Checklist

Use this before every government form goes live.

Labels

  • Every field has a visible, persistent label
  • Every label is programmatically associated with its field (not just visually adjacent)
  • No field relies on placeholder text as its sole label
  • Labels are descriptive enough to be understood out of context

Required Fields

  • Required fields are indicated with visible text not relying on color alone
  • Required fields have required and aria-required="true" attributes
  • The meaning of any symbols used to indicate required fields is explained in text

Error Handling

  • Error messages appear in an accessible error summary announced by screen readers
  • Focus moves to the error summary when form submission fails
  • Each error message identifies the field by name and specifies the correct format
  • Individual error messages are associated with their fields via aria-describedby
  • Errored fields have aria-invalid="true"
  • Error states are communicated by more than color alone

Keyboard Navigation

  • All fields and interactive elements are reachable by keyboard
  • Tab order follows the logical visual sequence of the form
  • No keyboard traps exist anywhere in the form
  • All custom components (date pickers, dropdowns, file uploads) are fully keyboard operable

Multi-Step Forms

  • Progress indicators communicate current step to screen readers
  • Focus is managed deliberately when advancing between steps
  • Validation occurs at each step boundary

Session and Timeouts

  • Session timeout warnings are announced to screen readers
  • Timeout warnings provide sufficient time to respond
  • The session extension action is keyboard accessible

Testing

  • Keyboard-only completion test passed
  • Screen reader test passed (NVDA + Chrome and VoiceOver + Safari)
  • Automated axe scan shows no violations
  • 200% zoom test passed

 

Related: 

ADA Compliance Checklist

Accessibility Remediation Log

WCAG 2.1 AA Explained

How to Make a PDF Accessible

How to Write Alt Text for Government Images, Charts, and Maps

How to Audit Your CMS for Accessibility

How to Train Your Government Staff on Accessibility

 

FAQ: Accessible Online Forms for Government Services

What is the most common accessibility failure in government online forms? 

Unlabeled form fields are the most pervasive failure — fields that have a visible label positioned near them but no programmatic association between the label and the input. When a screen reader user focuses on an unlabeled field, they hear only "edit text" with no indication of what information is being requested. The second most common failure is inaccessible error handling — error states that appear visually but fire no screen reader announcement, leaving users who rely on assistive technology with no indication that their form submission failed.

What is the difference between a placeholder and a label, and why does it matter for accessibility? 

A label is a persistent, programmatically associated text element that describes what a form field is asking for. It remains visible regardless of the field's state. A placeholder is hint text that appears inside a form field when it is empty and disappears when the user starts typing. Placeholders are not labels because they disappear at the exact moment a user is filling in the field, leaving users with cognitive disabilities who type slowly and forget what a field is asking for, and because placeholder text frequently fails color contrast requirements in its default styling. Every form field must have a visible, persistent label. Placeholders may be used as supplementary format hints but never as the sole field identifier.

How should error messages be implemented to be accessible to screen reader users? 

Accessible error messages require three things. First, the error must be announced to screen readers when it appears — the most reliable approach is an error summary at the top of the form using role="alert" with focus moved to the summary when form submission fails. Second, each error message must identify the field by name and describe the correct input specifically — "Phone number: Please enter a valid 10-digit number in the format 555-555-5555" rather than just "Invalid input." Third, each individual error message must be associated with its field using aria-describedby so that when focus lands on the errored field, both the label and the error message are announced together.

What is a keyboard trap and how do I test for one in a government form? 

A keyboard trap is a situation where keyboard focus enters a component — a dropdown, a modal dialog, a date picker — and cannot be exited using keyboard commands. The user is stuck and cannot continue navigating the form without using a mouse. To test for keyboard traps: put your mouse aside and use only the Tab key (forward), Shift+Tab (backward), Escape, and arrow keys to navigate through the entire form. If at any point you cannot exit a component or advance to the next field, that is a keyboard trap. Keyboard traps are a WCAG Level A failure — one of the most severe accessibility violations.

Are session timeouts accessible concerns for government forms? 

Yes. Session timeouts that expire without warning or that provide warnings that are not announced to screen readers create a significant barrier for users who rely on assistive technology and may navigate more slowly, and for users with motor disabilities who need more time to complete complex forms. WCAG 2.2.1 requires that time limits be adjustable or provide a warning with sufficient time to respond. The warning dialog must be announced to screen readers using role="alertdialog", focus must move to the dialog when it appears, and the option to extend the session must be keyboard operable.

Should we use a third-party form builder or build forms in-house for accessibility? 

Either approach can produce accessible forms — the question is whether accessibility is a requirement in the tool selection or build decision. For third-party form builders, request a VPAT and test the builder's output with keyboard navigation and a screen reader before committing to the platform. Many popular form builders produce significant accessibility failures in their default output. For in-house builds, follow the requirements in this guide and validate with the four-test protocol before launch. The form builder or development approach matters less than the accessibility testing and validation process applied to whatever is built.

 

Share this post