Accessible forms for ecommerce: labels, errors and validation
Forms are where ecommerce happens. Checkout, account creation, address entry, payment details. Every one of these is a form. And forms are among the most common sources of WCAG failures on ecommerce sites. A 2024 WebAIM survey found that 45% of tested forms had unlabeled fields. For ecommerce stores, that number is higher because checkout forms are often assembled from third-party components with no accessibility review.
This guide covers every layer of accessible form design: how labels work, how to handle errors, how validation should behave, and the autocomplete attributes that make forms faster for everyone.
How label association works
A form field is accessible when a screen reader can announce its purpose when the user focuses it. There are three ways to associate a label with an input.
The first is explicit association using for and id. The for attribute on a label element matches the id attribute on the input. This is the most reliable method across all assistive technologies.
The second is implicit association by wrapping the input inside the label element. This works in most screen readers but has inconsistent behavior with some older combinations of JAWS and Internet Explorer. For modern browser support, it is reliable.
The third is aria-label or aria-labelledby, covered in depth in our ARIA labels guide. These are ARIA attributes that override or supplement the accessible name. aria-label takes a string value directly. aria-labelledby takes the id of another element whose text becomes the label. Use these when a visible label is not possible or when you need to combine multiple text strings into one label.
What does not work: placeholder text as the only label. This is the most common form accessibility failure on ecommerce sites. Placeholder text disappears when the user starts typing. Users cannot review what a field requires while entering data. Screen readers handle placeholder text inconsistently. WCAG 1.3.1 requires that form fields have programmatically determinable labels. Placeholder alone does not satisfy this.
Required field indicators
WCAG 3.3.2 requires that labels describe the purpose of fields, including which ones are required. The common asterisk convention works if you explain it. A note at the top of the form (or fieldset) saying "Fields marked with * are required" satisfies the criterion. The asterisk itself must not be inside the label text in a way that confuses screen readers.
The better approach: use aria-required="true" on required inputs. Screen readers announce "required" after the label. You can also use the HTML required attribute, which triggers native browser validation and sets aria-required implicitly. Do not rely on the asterisk alone without an explanation.
If all fields in a section are required, say so at the top: "All fields are required." This removes the need to mark each individual field and reduces visual noise.
WCAG 3.3.1: Error Identification
When a form submission error occurs, the item in error must be identified and the error described to the user in text. This is a Level A criterion, meaning it is a baseline requirement.
Three things are required: the user must know an error occurred, they must be able to identify which field has the error, and they must understand what the error is.
Common failures: turning a field border red without any text explanation (color alone is insufficient per WCAG 1.4.1), moving focus to the top of the page with a generic "Please fix the errors below" message without linking to the fields, or displaying error messages that describe the system state rather than the problem ("Invalid input" instead of "Enter a valid email address").
The error message must be programmatically associated with the field. Use aria-describedby on the input, pointing to the id of the error message element. When the user focuses the input, the screen reader announces both the label and the error description.
For checkout address validation specifically: "Address not found" is insufficient. "We could not verify this address. Check the house number and postcode and try again" tells the user what to do.
WCAG 3.3.3: Error Suggestion
When an error is detected and suggestions are known, the suggestion must be provided to the user, unless doing so would jeopardize security or purpose.
This is Level AA. It goes beyond identifying the error to providing specific guidance. For a date field that expects MM/DD/YYYY, detecting "15/03/2025" and responding with "Dates should be in MM/DD/YYYY format. Did you mean 03/15/2025?" is the ideal implementation.
For credit card numbers: detect the number of digits and identify the card type. "Visa cards have 16 digits. You entered 15 digits" is more useful than "Invalid card number."
Password requirements should be shown before submission, not after. If your password must be 8+ characters with a number and a symbol, display those requirements adjacent to the field before the user starts typing. This is not a WCAG requirement, but it prevents the error from occurring.
WCAG 3.3.4: Error Prevention for legal and financial transactions
For pages that cause legal commitments or financial transactions, at least one of three conditions must be met: submissions are reversible, data is checked for errors and the user has opportunity to correct them, or a mechanism is available to review and confirm the submission before finalizing.
For ecommerce, the "review and confirm" pattern satisfies this criterion. The order review step in checkout where the user can see their items, address and payment method before clicking "Place order" is exactly what 3.3.4 requires.
The review step must give users a way to go back and edit. A "Change" link next to each section (items, address, payment) that returns focus to the relevant part of the form satisfies the criterion.
Returns and cancellation policies address the reversibility condition. If your store allows order cancellation within a window, you satisfy 3.3.4 through reversibility. Document this clearly in the review step.
Inline validation vs summary validation
There are two validation patterns: validate on blur (inline, per field) and validate on submit (summary, all errors at once). Both can be accessible. Both can fail.
Inline validation that triggers on every keystroke is almost always harmful. Announcing "Invalid email" while the user is still typing fragments their input experience. Screen readers announce the error live, interrupting their typing. The right trigger for inline validation is on blur (when the field loses focus) or after a debounce period.
When validation triggers on blur, the error message must be inserted into the DOM adjacent to the field and announced via a live region or by moving focus. If you insert the error message but do not announce it, keyboard users who have already moved on will not know an error was set.
Summary validation on submit works well if you: move focus to an error summary at the top, list each error as a link that jumps to the affected field, and also mark each field with the inline error. Proper keyboard navigation is essential here so users can follow error links back to their fields. Summary-only validation without field-level error markers makes it hard for users to identify which field corresponds to which error.
The best pattern combines both: inline validation on blur for immediate feedback, with a summary on submit that lists all errors with links. This serves keyboard users, screen reader users and sighted users equally.
WCAG 1.3.5: Identify Input Purpose
Input fields that collect personal data must have an autocomplete attribute that identifies the purpose of the field. This is Level AA and applies to any input that collects one of the 53 types of personal data listed in the WCAG spec.
The purpose is to allow browsers and assistive technologies to autofill and to allow users to apply their own symbols or images to field labels (e.g., a person with cognitive disabilities who maps the "email" concept to a personal icon).
For a checkout form, the critical autocomplete values are:
name: full name fieldgiven-name/family-name: separate first and last name fieldsemail: email addresstel: phone numberaddress-line1,address-line2: street address linesaddress-level2: cityaddress-level1: state or provincepostal-code: postal codecountry: country selectorcc-name: name on cardcc-number: card numbercc-exp: expiry datecc-csc: security codenew-password/current-password: password fields
Note: autocomplete="off" on payment fields is a common mistake. PCI DSS guidance does not prohibit browser autocomplete for cardholder data fields. Disabling autocomplete breaks password manager integration and forces users to manually transcribe card details, increasing error rates.
Fieldset and legend for grouped fields
When multiple form fields are logically related, they should be grouped with a fieldset element and labeled with a legend. Screen readers announce the legend text when the user enters the group, giving context.
The classic ecommerce use case: card expiry date split into month and year selects. Without a fieldset, the user hears "Month" and "Year" without knowing these relate to card expiry. With a fieldset and legend "Card expiry date", they hear "Card expiry date. Month. Year."
Radio button groups for options like "Ship to this address" vs "Ship to a different address" must use fieldset/legend. The legend describes the group question. The individual radio buttons are the answers. Without this grouping, a screen reader user hears isolated options without knowing what they are choosing between.
Nested fieldsets (a fieldset inside a fieldset) are technically allowed but have inconsistent screen reader support. Avoid nesting more than one level deep.
Accessible date pickers
Date pickers are one of the most inaccessible widgets in ecommerce, particularly on mobile devices. Calendar widgets built with div elements and click handlers are almost always unusable with a keyboard and unannounced by screen readers.
The most accessible approach for most ecommerce use cases (delivery date selection, gift message scheduling) is three separate select elements for day, month and year, wrapped in a fieldset. This is not the most elegant UI, but it is universally accessible.
If you need a calendar widget, the ARIA Authoring Practices Guide (APG) defines the expected keyboard behavior for a date picker dialog: arrow keys navigate days, Enter selects, Escape closes, Page Up/Down move months, Shift+Page Up/Down move years. Any date picker widget that does not implement this pattern has keyboard accessibility failures.
The native HTML input type="date" is accessible in modern browsers and should be considered for most cases. Its appearance varies by browser, which is why many teams avoid it, but from an accessibility standpoint it is the lowest-effort accessible solution.
Placeholder text: what it can and cannot do
Placeholder text can supplement a label. It cannot replace one. Placeholder disappears on focus in some browsers, disappears on input in all browsers, has low contrast by default (1.4.1 failure), and is not reliably announced by all screen reader and browser combinations.
Valid uses for placeholder text: showing the expected format ("MM/DD/YYYY"), showing an example value ("e.g. john@example.com"), providing a hint that is not critical to understanding the field.
Invalid uses: as the only label for a field, for required vs optional designation, for error messages.
If you must use placeholder text, ensure it meets the 4.5:1 contrast ratio for normal text (not the 3:1 that applies to large text). The WCAG exception for placeholder text at lower contrast is not justified on accessibility grounds.
Quick checklist for ecommerce checkout forms
- Every input has a visible, persistent label associated via
for/idoraria-labelledby - Required fields use
aria-required="true"or the HTMLrequiredattribute - Error messages are in text, adjacent to the field, associated via
aria-describedby - Errors describe what is wrong and how to fix it, not just that something is wrong
- All personal data fields have correct
autocompleteattributes - Related fields (card expiry, address parts) are wrapped in fieldset/legend
- Date inputs are keyboard-operable with full APG-compliant navigation or native inputs
- An order review step allows inspection and editing before final submission
- Paste is enabled on all password and confirmation fields
- Placeholder text is not the only label for any field
Frequently asked questions
- Can placeholder text replace form labels for accessibility?
- No. Placeholder text disappears when users start typing and is not reliably announced by all screen readers. WCAG 1.3.1 requires programmatically determinable labels. Always use a visible label element associated with each input.
- How should form errors be displayed for accessibility?
- Error messages must be in text (not color alone), identify the specific field with the problem, describe what is wrong and be programmatically associated with the field using aria-describedby. Focus should move to the first error on submission.
- What autocomplete attributes are required on checkout forms?
- WCAG 1.3.5 (Level AA) requires autocomplete attributes on personal data fields. Key values include given-name, family-name, email, tel, address-line1, postal-code, cc-number and cc-exp.
Complyko scans your checkout forms for label failures, missing autocomplete attributes and error handling violations. See exactly which fields fail and how to fix them.
Get your free scan →