role=img Elements Need Alternative Text: How to Fix It
- November 6, 2023
- Accessibility, Images

This check fires when an element carrying role="img" has no accessible name — no aria-label, no aria-labelledby, nothing. You have told the browser "treat this as a picture," then handed the screen reader a picture with no caption. It gets announced as a bare, meaningless "image," or worse, its inner text nodes leak through in a garbled mess.
Why role="img" needs a name and a plain img usually doesn't
A normal <img> gets its accessible name from the alt attribute. But people apply role="img" to things that are not img elements — inline SVGs, icon-font <span>s, sprite <div>s, emoji clusters, ASCII art. Those elements have no alt attribute to fall back on. When you promote them to the image role, you take on the job of naming them yourself. Skip it and assistive tech has nothing to read out.
The role also does something sneaky: it tells the screen reader to ignore the element's children as content and treat the whole thing as one atomic image. So if you have a decorative icon font that renders a private-use glyph, and you add role="img" with no label, the user hears silence or a spoken code point. Rough.
Real failing example
<!-- Inline SVG rating stars, no accessible name -->
<span role="img">
<svg viewBox="0 0 24 24" width="16" height="16"><path d="M12 2l3 7h7l-6 4 2 8-6-4-6 4 2-8-6-4h7z"/></svg>
<svg viewBox="0 0 24 24" width="16" height="16"><path d="M12 2l3 7h7l-6 4 2 8-6-4-6 4 2-8-6-4h7z"/></svg>
</span>
<!-- Icon-font wrapper, announced as nothing useful -->
<i class="icon-cart" role="img"></i>The star cluster is announced as "image" with no rating. The cart icon — a private-use font glyph — gets read as empty or as a raw character.
The fix
<span role="img" aria-label="Rated 2 out of 5 stars">
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M12 2l3 7h7l-6 4 2 8-6-4-6 4 2-8-6-4h7z"/></svg>
<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M12 2l3 7h7l-6 4 2 8-6-4-6 4 2-8-6-4h7z"/></svg>
</span>
<i class="icon-cart" role="img" aria-label="Shopping cart"></i>The aria-label becomes the accessible name. Marking the inner SVGs aria-hidden="true" stops their own guts from being announced twice. Note the label describes the meaning ("Rated 2 out of 5 stars"), not the mechanics ("two filled star shapes"). If the icon is purely decorative — it repeats adjacent visible text — drop the role entirely and add aria-hidden="true" instead of naming it.
Which naming method for which element
| Element you gave role="img" | Best naming method | Also do |
|---|---|---|
Inline <svg> icon | aria-label on the role="img" host | Hide inner shapes with aria-hidden="true" |
Icon-font <span>/<i> | aria-label | Ensure the glyph itself is not read |
Sprite / background-image <div> | aria-label or aria-labelledby | — |
| Emoji sequence (e.g. flags) | aria-label describing the emoji meaning | Wrap in the role="img" span |
| Decorative, repeats nearby text | No name — remove role, add aria-hidden="true" | Keep it out of the a11y tree |
How to detect it
- axe DevTools. The svg-img-alt and role-img-alt rules flag any
role="img"with no accessible name, and give you the exact selector. - Lighthouse. The Accessibility audit "ARIA
role="img"elements do not have an accessible name" lists every offender. - Screen reader pass. Turn on VoiceOver (Cmd+F5 on macOS) or NVDA, arrow to the element, and listen. If it says "image" and nothing else, it is unnamed.
- Console query.
document.querySelectorAll('[role="img"]:not([aria-label]):not([aria-labelledby])')returns every element missing a name.
How to fix it
- List every
role="img"element from the console query above. - For each, decide: is it meaningful or decorative?
- Meaningful → add an
aria-label(oraria-labelledbypointing at existing visible text) describing what it conveys. - Decorative → remove
role="img"and addaria-hidden="true"so it stays out of the accessibility tree. - Hide inner SVG/glyph nodes with
aria-hidden="true"so nothing double-announces. - Re-run axe to confirm zero role-img-alt violations.
Frequently asked questions
Can I use title instead of aria-label?
Not reliably. title produces a tooltip and its accessible-name support is inconsistent across screen readers, especially on non-interactive elements. Use aria-label or aria-labelledby; treat title as a bonus, never the primary name.
What's the difference between this and a plain SVG with no alt?
They overlap. A standalone <svg> intended as an image should carry role="img" plus a name, so the two checks often fire together. The broader SVG rules are covered in SVG Images and Graphics Require Accessible Text.
How long should the label be?
Long enough to convey the meaning, short enough not to annoy. "Shopping cart," "Rated 2 out of 5 stars," "Verified account." Describe purpose, not pixels. Overlong labels have their own downside — the same discipline as alt text over 100 characters.
Does this affect regular image SEO?
Search crawlers lean on real alt attributes on <img> for image indexing; role="img" plus aria-label is primarily an accessibility signal, not an image-search one. If you want the graphic in image search, use a genuine <img> with alt. Background on that is in the Alt Text glossary entry.
What if the icon already sits next to a text label?
Then it is decorative — do not name it twice. Remove the role and add aria-hidden="true". Duplicate announcements are as bad as missing ones. Related discernible-name logic lives in Links Must Have Discernible Text.
Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.
About SEO ProCheck
Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.
Work With Me
Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.







