Images and form fields with no accessible name
why is my site failing accessibility checks for missing alt text and form labels Your rendered HTML ships img tags without alt attributes, inputs with only a placeholder instead of a label, and icon buttons with no accessible name. Screen readers announce nothing useful, form autofill misfires, and Lighthouse or axe scores drop. Fix it by adding alt text, wiring label-for pairs, and adding aria-label to icon controls.
Seen in 21 of 450 scanned projects (5%). Based on rendered-HTML audits across 450 scanned projects.
How to tell you have it
- Screen reader users report forms as unusable or silent
- Lighthouse or axe-core accessibility score sits below 90
- Images pop into view and shift layout after load
- Icon-only buttons read as 'button' with no purpose in VoiceOver or NVDA
- Streaming AI output updates the page but screen readers never announce it
Why it matters
An img with no alt attribute is not just a lint warning, it is a hole in the page's information model. A screen reader either reads the filename aloud or skips the image entirely, and either way a sighted user's context is gone for someone relying on audio. This is the single most common accessibility complaint in production audits, and it is also the cheapest to fix, which makes leaving it unfixed harder to justify to anyone who reviews the site later.
Placeholder text is not a label. The moment a user starts typing, the placeholder disappears, so anyone who gets interrupted, or anyone using voice control or a screen reader that never rendered the placeholder as an announced label in the first place, loses track of what the field is for. Browsers and password managers also key off label associations, not placeholder strings, so autofill quality degrades quietly alongside accessibility.
Icon-only buttons without an aria-label are a coin flip for assistive tech. A trash-can SVG with no text conveys nothing to a screen reader, so the user hears 'button' and has to guess, tab away, or abandon the flow. The same problem shows up in dashboards with icon toolbars, chat UIs with a send-arrow button, and mobile-style hamburger menus, all patterns that ship fast and get accessibility bolted on later, if at all.
Images with no width and height attributes force the browser to reflow the page once the image finishes loading, which is the textbook cause of cumulative layout shift. Users end up clicking the wrong link because a button jumped down the page a half second after the page looked ready. This is a Core Web Vitals metric Google actually scores, so it is not purely a cosmetic issue, it affects ranking and it affects real conversion on forms and checkout flows.
How Heygents detects it
Deep Scan pulls the rendered HTML with curl -s against the live URL and greps for img tags missing alt, input and textarea elements with a placeholder but no matching label or aria-label, button and a tags that contain only an svg or icon class with no text or aria-label, and img tags missing width or height. It also checks for a main element with no id and a skip-to-content anchor near the top of the body.
How to fix it
- Add real alt text to content images, and empty alt to decorative ones Every meaningful image needs alt text describing what it conveys, not what it looks like. A purely decorative image (a divider, a background flourish) should get alt="" so screen readers skip it silently instead of reading a useless description.
- Replace placeholder-only fields with a real label Pair every input with a label using for/id, or wrap the input in the label element. Keep the placeholder if you want, but it should supplement the label, not replace it.
- Name icon-only buttons with aria-label Any interactive element whose only content is an icon needs an aria-label that states the action, not the icon's shape.
- Announce streamed content with an ARIA live region If your UI streams AI-generated output token by token, wrap the output container in aria-live="polite" so a screen reader announces the update once it settles, instead of staying silent through the whole response.
- Add a skip link and an id on main, fix a fake tablist Give keyboard users a way to jump past the nav, and make sure anything carrying role="tab" actually behaves like a tab: focusable, arrow-key navigable, and paired with a role="tabpanel" region. A div with a click handler and a tab role is worse than no role at all, because it promises behaviour assistive tech then cannot find.
- Add an automated accessibility gate to CI Run axe-core against your built pages in CI so a missing alt attribute or unlabeled input fails the pipeline instead of shipping. Treat it the same as a lint failure, not an optional report.
Add real alt text to content images, and empty alt to decorative ones
<!-- meaningful -->
<img src="/chart-q3-revenue.png" alt="Q3 revenue grew 18% quarter over quarter" width="640" height="360">
<!-- decorative -->
<img src="/divider.svg" alt="" width="24" height="24">
Replace placeholder-only fields with a real label
<label for="email">Email address</label>
<input id="email" name="email" type="email" placeholder="you@example.com">
Name icon-only buttons with aria-label
<button type="button" aria-label="Delete project" onclick="deleteProject(id)">
<svg class="icon-trash" aria-hidden="true"><!-- ... --></svg>
</button>
Announce streamed content with an ARIA live region
<div id="stream-output" aria-live="polite" aria-atomic="false">
<!-- tokens appended here as they arrive -->
</div>
Add a skip link and an id on main, fix a fake tablist
// Layout shell: a real skip link plus a labelled main landmark
export function Shell({ children }) {
return (
<>
<a className="skip-link" href="#main">Skip to content</a>
<nav aria-label="Primary">{/* ... */}</nav>
<main id="main" tabIndex={-1}>{children}</main>
</>
);
}
// Icon-only button: the accessible name comes from aria-label, not the glyph
<button type="button" aria-label="Remove upload" onClick={clear}>
<XIcon aria-hidden="true" />
</button>
Add an automated accessibility gate to CI
npm install --save-dev @axe-core/cli
npx axe http://localhost:3000 --exit
Find this in your own projects, automatically
Heygents runs a read-only Deep Scan across every project you own, finds issues like this one, and hands you a ready-to-run fix an AI agent can execute and verify. A solo developer gets the audit, the backlog and the fix loop in one place.
Open Heygents →Frequently asked questions
Do all images need alt text, even icons and logos?
Meaningful images need descriptive alt text: logos, charts, avatars, product photos. Purely decorative images like spacers or background flourishes should get alt="" so a screen reader skips them instead of reading noise. The test is simple: if removing the image would lose information, write real alt text; if not, leave it empty but present.
Is a placeholder enough if the field name is obvious, like a search box?
No. Placeholder text disappears on focus and is not reliably exposed as an accessible name by every browser and assistive technology combination. Even an obvious search box should carry a visually hidden label or aria-label so screen reader users and password managers get a stable, always-present name for the field.
How do I label an icon-only button without cluttering the visual design?
Use aria-label on the button itself, or a visually-hidden span of text inside it. Both keep the compact icon-only look while giving assistive technology a real accessible name. Avoid relying on the title attribute alone, since it is inconsistently announced across screen readers and unavailable on touch devices.
Why does a role="tablist" without real tab behavior fail accessibility checks?
ARIA roles describe a contract, not just a label. Adding role="tablist" and role="tab" without arrow-key navigation, aria-selected state, and matching role="tabpanel" content tells assistive tech a widget exists that does not actually behave that way, which is worse than no ARIA at all because it sets a false expectation.
Can I catch these issues before they reach production?
Yes. Add an automated tool like axe-core or Lighthouse CI to your build pipeline and fail the build on new violations. Combine that with a manual pass using a real screen reader (VoiceOver or NVDA) on your core flows, since automated tools catch roughly a third of real accessibility issues and miss things like whether a label's wording actually makes sense.