We asked a mainstream AI assistant for one thing: a simple, accessible signup form. Name, email, password, a submit button. Nothing exotic.
What came back looked clean. Every field had a label sitting right above it. The button had a nice rounded corner and a visible focus ring in the screenshot we took. If you were skimming the rendered page, you would have signed off on it in about four seconds.
Then we stopped reading the code and started using it the way a real person with a disability actually would: tab key first, screen reader second, mouse never. That is where the review actually started, and that is where things fell apart.
The stat that matches what we saw
We were not surprised, because this lines up with what the research already says about AI-generated front-end code.
The Stat: A 2025 academic study comparing human- and LLM-generated code (evaluating GPT-4o and Qwen2.5-Coder) found that AI-generated code handles "basic features like color contrast and alternative text" reasonably well, but "struggles with complex issues such as ARIA attributes." (Source: arXiv 2503.15885)
That is almost exactly the shape of what we found. The surface-level stuff, the part a human reviewer can eyeball in a Figma comparison, was fine. The relationship-based stuff, the invisible wiring that only a screen reader or an assistive technology API actually reads, was where it broke.
What actually happens when you tab through it
We opened the generated form, put the mouse away, and started pressing Tab.
The first problem showed up immediately. Clicking directly on the word "Email" did not move focus into the email field. In a properly built form, clicking a label is supposed to jump focus straight to its input, because the browser knows the two are connected. Here, nothing happened. That single, boring behavior is the fastest way to tell whether a <label> is actually wired to its <input> with a for attribute, or whether it is just a <div> or <span> sitting nearby that happens to look like a label.
This is not a cosmetic detail. It is the entire substance of WCAG 3.3.2 Labels or Instructions, which requires that a visible label be programmatically associated with its input, not just visually adjacent to it. A sighted mouse user never notices the difference. A screen reader user notices instantly, because instead of hearing "Email, edit text," they hear "edit text," with no idea what they are supposed to type.
The second problem was worse, and it only showed up when we deliberately submitted the form with an invalid email address. A red message appeared under the field: "Please enter a valid email." Visually, it was right there, two inches from the input. But when we turned on a screen reader and tabbed back into that field, it read only "Email, edit text, invalid." No message. No explanation. No fix instruction. The user is told something is wrong and given nothing to act on.
That is a direct miss on WCAG 3.3.1 Error Identification, which requires that when an error is detected, it has to be identified and described in text that is actually delivered to the user, not just placed near the field. In practice this means the error text needs an id, and the input needs aria-describedby pointing at that id. The AI-generated markup had never made that connection. The two pieces sat next to each other on the page, and to a screen reader they were strangers.
The one thing it did get right, interestingly, was color contrast. Every input border and every text label passed a contrast check on the first try, no adjustments needed. That tracks with the research above: the visual, measurable stuff is easy for a model to get right because it is just a number. The relational, invisible-to-the-eye stuff is where the model has nothing to check itself against, because it never actually experiences the page the way an assistive technology does.
The pattern, laid out plainly
| What we tested | Result | Root cause |
|---|---|---|
| Visible label present | Passed | Text existed on the page |
Label tied to input via for/id |
Failed | Association never coded |
| Focus moves on label click | Failed | Direct consequence of the above |
| Error text visually shown | Passed | Text existed on the page |
| Error text read by screen reader | Failed | No aria-describedby link |
| Input color contrast | Passed | Measurable value, easy to check |
| Focus-visible outline on all inputs | Failed | Outline removed by default CSS reset |
Here is the checklist we now run on every single AI-generated form before it goes anywhere near production:
- Click every label and confirm focus jumps into its input
- Trigger every validation error and listen with a screen reader, not just look
- Confirm each error message has an
idreferenced by the input'saria-describedby - Tab through the entire form and confirm a visible focus outline never disappears
- Check contrast on inputs, placeholder text, and error text separately
- Submit the form using only the keyboard, start to finish, no mouse
None of this required exotic tooling. It required actually using the thing the way a disabled user would, instead of trusting that clean-looking markup means clean-behaving markup.
The takeaway
An AI assistant can absolutely produce a form that looks finished, and it will often get the easy, measurable things right without being asked twice. The harder, relational parts of accessibility, the ones that only surface when you stop looking at code and start operating the interface with a keyboard or a screen reader, are exactly where it still falls short. That gap is precisely why we put together the prompt we use to catch 80% of these issues before they ship, so teams shipping AI-generated UI have a repeatable check before it goes live rather than after a user reports it.
If you want to get a real accessibility review of any AI-generated code, before it becomes a support ticket or worse, get a free audit of your actual production code. We would rather find the broken label association now than have your users find it for you.
