You make an accessible form with visible labels that are linked to their field in the code, the right autocomplete attributes, error messages in text next to the field and an order that works with only a keyboard. For an online shop, this applies even more strictly to the checkout. That is where a visitor who gets stuck drops out immediately, and that is what the European Accessibility Act looks at specifically.
This article is part of our complete guide to website accessibility. We go through the WCAG 2.2 success criteria that most often go wrong in forms, with code examples you can use straight away. Every criterion number and level comes from the official WCAG 2.2 specification.
If you would like the bigger picture of WCAG 2.2 and the new criteria first, read WCAG 2.2 explained.
Why the European Accessibility Act affects e-commerce
The European Accessibility Act explicitly names e-commerce services as a service that must be accessible. In Directive (EU) 2019/882, "e-commerce services" are listed in Article 2(2)(f). Article 3 defines them as services provided at a distance through websites and mobile device-based services, at the individual request of a consumer, with a view to concluding a consumer contract. Member States apply the rules from 28 June 2025.
Annex I, Section IV, point (g) makes it concrete for online shops. You provide the available accessibility information about the products you sell. And the functions for identification, security and payment must be perceivable, operable, understandable and robust. Those are exactly your login, account and checkout forms.
A microenterprise that provides services is exempt from these requirements under Article 4(5). Whether the EAA applies to your business is covered in European Accessibility Act. This article is an explanation, not legal advice; if in doubt, consult a lawyer.
Labels: a visible, linked name for every field
Every input field needs a visible label that is linked to the field in the code. Criterion 3.3.2 Labels or Instructions (level A) asks for labels or instructions where input is required. Criterion 1.3.1 Info and Relationships (level A) asks that the relationship between label and field can also be determined programmatically, so that a screen reader reads out the label when the field receives focus.
The simplest way is a label element with a for attribute that refers to the field's id. Clicking the label then also places the cursor in the field, which helps on small screens.
<label for="email">Email address</label>
<input type="email" id="email" name="email" autocomplete="email" required>
<!-- Don't: a placeholder only -->
<input type="email" placeholder="Email address">
A placeholder is not a label. It disappears when you type, often has little contrast and can't be checked once the field is filled in. Use a placeholder for an example at most, such as "SW1A 1AA".
Autocomplete: let the browser do the work
With autocomplete attributes you tell the browser what kind of data a field asks for, so it can fill it in automatically. Criterion 1.3.5 Identify Input Purpose (level AA) asks that the purpose of fields collecting information about the user can be determined programmatically. WCAG lists the valid purposes in a fixed list, including name, email, telephone, address, postcode and payment details.
For people with a motor or cognitive disability, this saves a lot of typing and errors. For everyone, it makes the checkout faster.
<label for="name">Full name</label>
<input id="name" name="name" autocomplete="name">
<label for="street">Street address</label>
<input id="street" name="street" autocomplete="street-address">
<label for="postcode">Postcode</label>
<input id="postcode" name="postcode" autocomplete="postal-code">
<label for="town">Town or city</label>
<input id="town" name="town" autocomplete="address-level2">
<label for="tel">Phone number (optional)</label>
<input type="tel" id="tel" name="tel" autocomplete="tel">
Required fields and grouping with fieldset
Mark required fields both visibly and in the code, and group fields that belong together with fieldset and legend. The required attribute makes a screen reader announce "required". If you use an asterisk, explain at the top what it means. If almost all fields are required, it's better to mark the few optional fields instead.
A fieldset with a legend falls under criterion 1.3.1. It is mainly needed for radio buttons and checkboxes, where the label of a single option means nothing without the question. "Collection" says little; "Delivery method: collection" does.
<fieldset>
<legend>Delivery method</legend>
<input type="radio" id="delivery-home" name="delivery" value="home" required>
<label for="delivery-home">Home delivery</label>
<input type="radio" id="delivery-pickup" name="delivery" value="pickup-point">
<label for="delivery-pickup">Pickup point</label>
</fieldset>
Also use fieldset to separate the billing address from the delivery address. Without a group, a screen reader user hears "Postcode" twice without knowing which address it belongs to.
Error messages and error suggestions
An error message must say in text which field is wrong and what the problem is. Criterion 3.3.1 Error Identification (level A) asks that an automatically detected input error is identified and described in text. A red border alone is therefore not enough. Criterion 3.3.3 Error Suggestion (level AA) goes further: if you know how to fix the error, you give that suggestion, unless doing so would jeopardise security or purpose.
"Invalid input" doesn't meet 3.3.3. "Enter a postcode such as SW1A 1AA" does. Link the message to the field with aria-describedby and mark the field with aria-invalid, so a screen reader reads out the error when the field receives focus.
<label for="postcode">Postcode</label>
<input id="postcode" name="postcode" autocomplete="postal-code"
aria-invalid="true" aria-describedby="postcode-error">
<p id="postcode-error">Enter a UK postcode, for example SW1A 1AA.</p>
For a long form, a summary of all errors at the top, with links to the fields, helps. After submitting, move the focus to that summary. Only use ARIA such as aria-invalid where it adds something; WAI-ARIA supplements HTML, but doesn't replace a solid foundation.
For the final step of an order, criterion 3.3.4 Error Prevention (level AA) also applies. For submissions with financial or legal consequences, the user must be able to review and correct the input, reverse it, or explicitly confirm it. A review page before "Place order" usually meets this.
Focus order, keyboard and target size
A form must be fully operable with a keyboard, in a logical order, with visible focus. Criterion 2.1.1 Keyboard (level A) asks that all functionality works with a keyboard. Criterion 2.4.3 Focus Order (level A) asks for an order that preserves meaning and operability. Criterion 2.4.7 Focus Visible (level AA) asks for a visible focus indicator.
Common errors in a checkout:
- A custom dropdown or date picker that only responds to a mouse click.
- A
tabindexwith a positive value, which makes the focus jump around the form. - A focus outline removed with CSS (
outline: none) without a replacement. - A fixed bar at the bottom that covers the focused field. WCAG 2.2 added criterion 2.4.11 Focus Not Obscured (Minimum, level AA) for this.
For touchscreens and people with tremors, the size of buttons and boxes matters. Criterion 2.5.8 Target Size (Minimum, level AA) asks for a target area of at least 24 by 24 CSS pixels. There are exceptions, including when there is enough space around the target, when there is an equivalent larger element, or for links in running text. Tiny checkboxes for the terms and conditions and minuscule plus and minus buttons in the basket are the well-known problem cases.
Redundant entry and time limits
Never ask for the same information twice in the same process. Criterion 3.3.7 Redundant Entry (level A), new in WCAG 2.2, asks that previously entered information is either filled in automatically or available to select. Exceptions are when re-entering is essential, required for security, or when the earlier information is no longer valid.
The best-known example in an online shop is the billing address. A checkbox saying "Billing address is the same as delivery address" conforms. A second, empty address form does not. Asking for a password twice falls under the security exception.
Time limits fall under criterion 2.2.1 Timing Adjustable (level A). If your checkout or basket has a time limit, the user must be able to turn it off, adjust it to at least ten times the default length, or be warned beforehand and given at least 20 seconds to extend it with a simple action. Exceptions are real-time events such as an auction, limits that are essential and limits longer than 20 hours. A session that silently expires after ten minutes and empties the basket is therefore a problem.
Logging in without puzzles
Logging in or confirming your identity must not require a cognitive test, such as remembering a password or retyping a code, unless there is an alternative or a mechanism to help. That is what criterion 3.3.8 Accessible Authentication (Minimum, level AA), new in WCAG 2.2, asks. The exceptions at AA are recognising objects and recognising your own content, such as a photo you uploaded yourself.
The Understanding page for 3.3.8 makes a few things concrete:
- Pasting must work. If you block pasting into the password field, or prevent a password manager from filling the field, you fail this criterion, unless there is another method.
- Retyping verification codes is not enough. A service that only allows a code to be retyped manually does not conform. The user must at least be able to paste the code.
- CAPTCHAs need a non-cognitive alternative, unless they involve object recognition. An audio CAPTCHA that you have to transcribe doesn't count as an alternative.
Practical alternatives to a CAPTCHA are an invisible background check, a hidden honeypot field, logging in via a link sent by email, or a passkey. Set autocomplete="current-password" or autocomplete="new-password" on password fields, so password managers recognise them. At level AAA (criterion 3.3.9), the exception for object recognition also no longer applies.
The payment step and payment provider iframes
The payment step is often the hardest part to make accessible, because some of it isn't in your own code. Many online shops show the card fields in an iframe from the payment provider, or send the customer to a payment page hosted by that provider. You usually can't change what happens in there yourself.
Yet it remains part of your ordering process, and the EAA explicitly mentions the payment function of an e-commerce service. Exactly how responsibility is split between you and your provider differs per situation and, if in doubt, calls for legal advice. What you can do in any case:
- Ask your payment provider for its accessibility information or statement, and for the WCAG version and level its payment components have been tested against.
- Test the payment step yourself with only a keyboard and with a screen reader, including an invalid entry and a 3D Secure check.
- Give an iframe a title that says what it contains, for example
title="Payment details", if you set it yourself. - Offer several payment methods, so a customer who gets stuck with one method can choose another.
- List known issues in your accessibility statement, with an alternative way to order.
How to check this on your own site
- Go through your entire ordering process using only a keyboard, from product page to confirmation. Note every place where the focus disappears or gets stuck.
- Check every field for a visible, linked label and the correct autocomplete value. The accessibility pane in DevTools shows which name a field gets.
- Submit the form with deliberate errors. Do you get an error message in text with a suggestion for each field, and does a screen reader read it out?
- Test logging in with a password manager and check that pasting works in password and code fields.
- Measure the target size of checkboxes, radio buttons and basket buttons on a phone.
- Run an automated scan on every step of the checkout. It finds missing labels and incorrect ARIA; the rest of this list remains manual work. You can read more about that combination in testing website accessibility.
Flowproof's accessibility check is included in the paid Pro and Business plans and tests your pages with axe-core against WCAG 2.2 A and AA. You can start for free and compare the plans on the pricing page.