4 Accessibility Mistakes AI Coding Assistants Make, and How to Catch Them
AI coding assistants are good at producing working components quickly. They learned from a huge amount of public code, and public code is full of accessibility mistakes — so the same mistakes come back in generated components, looking clean and passing a quick visual review.
Here are four that show up often, the WCAG criterion each one fails, and how to catch them before they merge.
## 1. A clickable `div` with no keyboard support (WCAG 2.1.1, 4.1.2)
Ask for “a clickable card” or “a custom button” and you’ll often get this:
// Works with a mouse. A keyboard user can't reach it or activate it.
<div className="btn" onClick={save}>Save</div>Adding `role=”button”` alone doesn’t fix it: the element still isn’t in the tab order and doesn’t respond to Enter or Space.
// Fix: use the element that already does all of this.
<button type="button" className="btn" onClick={save}>Save</button>A `<button>` is focusable, activates on Enter and Space, and is announced as a button. Reach for `role` and `tabIndex` only when no native element fits.
## 2. An `aria-label` that doesn’t match the visible text (WCAG 2.5.3)
Assistants like adding `aria-label` “for accessibility”, often with a more descriptive phrase than the button shows:
<! - Visible text "Buy now"; accessible name "Add product to basket" →
<button aria-label="Add product to basket">Buy now</button>The `aria-label` replaces the visible text as the accessible name. A voice-control user who says “click Buy now” gets nothing, because no control is called “Buy now”. WCAG 2.5.3 (Label in Name) requires the accessible name to contain the visible label.
<! - Fix: let the visible text be the name →
<button>Buy now</button>If you need more context for screen reader users, keep the visible words at the start of the name: `aria-label=”Buy now: Linen shirt”`.
Get Giriprasadpatil’s stories in your inbox
Join Medium for free to get updates from this writer.
## 3. A placeholder used as the label (WCAG 3.3.2, 1.3.1)
<input type="email" placeholder="Email address">The placeholder disappears as soon as someone starts typing, it’s usually low contrast, and it isn’t a reliable label. Give every input a visible, associated label:
<label for="email">Email address</label>
<input id="email" type="email" autocomplete="email">## 4. Focus outlines removed (WCAG 2.4.7)
Generated CSS often includes a reset like this:
*:focus { outline: none; }It removes the only sign of where a keyboard user is on the page. If the default ring doesn’t fit the design, replace it rather than removing it, and keep it to keyboard focus:
:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
}## Catching these in review
Each check below catches a different subset, so use more than one:
- **A linter in the editor.** `eslint-plugin-jsx-a11y` flags click handlers on non-interactive elements and inputs without labels while you type.
- **Prefer native elements in prompts and review.** Asking the assistant for “a `<button>`” or “a native `<dialog>`” gets better output than “a clickable element”.
- **A keyboard pass.** Tab through the new component. If you can’t reach or operate it, it fails.
- **A check of the rendered page.** Mistakes 1, 2 and 4 depend on the rendered page — computed names, focus styles, what’s focusable. ADAGuard loads the page in a real browser and checks those, including label-in-name. [Scan a page free](/free-accessibility-scanner).
Avoid “fix it at runtime” scripts as the safety net. A script that edits the page in each visitor’s browser leaves the source unchanged, so every mistake is still in the code the assistant learned from your repo. See [why overlays don’t fix accessibility](/accessibility-overlay-trap-legal-risk).
AI assistants are useful here too: once a failure is found, they’re good at applying a known fix across many files. The part they can’t do is notice that a component they just wrote doesn’t work with a keyboard. That takes a test.
Originally published at https://www.adaguard.io on October 17, 2026.







