ADA Compliance Professionals

    Role img elements must have alt text

    Last updated:

    Who it helps:
    Blind
    Standard:
    WCAG 2.2 Level A

    Elements with role="img" must include a text alternative

    Provide a text alternative for every role="img" element.

    This issue appears when a div or span is given role="img" without an accessible name. It impacts screen reader users and anyone relying on assistive tech to understand graphics.

    Why It Matters

    Screen readers announce images as "graphic" plus the accessible name. Without a name, users hear only "graphic" or nothing, missing critical information.

    People with low vision who zoom or use screen readers need concise text to understand visuals. If color conveys meaning, a text alternative communicates that meaning without relying on color perception.

    Accessible names also support voice control software by exposing a clear label for the image.

    Common Causes

    • Using div/span with role="img" but no aria-label or aria-labelledby.
    • Empty or whitespace-only aria-label values.
    • aria-labelledby points to a missing id or to content removed from the accessibility tree (e.g., display:none), yielding no name.
    • Relying on the element’s text content; role="img" does not expose children to assistive tech.
    • Using only the title attribute, which is unreliable and often not announced.
    • Marking decorative graphics with role="img" instead of hiding them from assistive tech.

    How to Fix

    1. Prefer semantic HTML when possible
      • If you are rendering an actual image, use <img> with an alt attribute.
      • Use role="img" on non-image elements only when necessary (e.g., CSS backgrounds, canvas output).
    2. Provide an accessible name for role="img"
      • Use aria-label for short, self-contained text (e.g., aria-label="Company logo").
      • Or use aria-labelledby to reference visible or visually hidden text nearby. Ensure the target element exists and has unique id.
      • Recommendation: Do not reference elements with display:none or visibility:hidden. Use a visually hidden utility class so the text remains in the accessibility tree.
    3. Keep text alternatives concise and meaningful
      • Describe purpose or information, not appearance alone (e.g., "Error: required field missing" vs. "Red exclamation icon").
      • Recommendation: Aim for a short phrase or one sentence. For complex charts, provide a brief name and link to a detailed description.
    4. Handle decorative graphics correctly
      • If the image conveys no information, remove role="img" and add aria-hidden="true" to hide it from assistive tech.
    5. Avoid unreliable naming sources
      • Do not rely on title as the only name. Use aria-label or aria-labelledby.

    Relevant WCAG 2.2

    • 1.1.1 Non-text Content (A): Provide text alternatives for non-text content.
    • 4.1.2 Name, Role, Value (A): Expose a programmatic name for user interface components.

    How to Test

    Keyboard check

    • Tab through the page. Non-interactive images should not receive focus. If an image is focusable, verify it has a meaningful name.

    Screen reader check

    • NVDA/JAWS (Windows): Use browse mode and navigate to the image. Expect "graphic" plus the accessible name.
    • VoiceOver (macOS): VO+Right/Left to the image. Confirm the announced text matches the intended meaning.

    Mobile/touch check

    • iOS VoiceOver / Android TalkBack: Swipe to the image. Confirm it announces a clear, concise name.

    Developer check

    • Use the browser’s Accessibility/ARIA inspector. Confirm Role = img and Name is populated with the correct text. Verify aria-labelledby references a real, not-hidden node or use aria-label.
    • Run an automated checker and resolve any "Element with role img is missing an accessible name" issues.

    Good Example

    HTML
    <!-- Using aria-label for a simple graphic rendered with CSS -->
    <div class="brand-mark" role="img" aria-label="Acme company logo"></div>
    
    <!-- Using aria-labelledby with visually hidden text for a chart preview -->
    <p id="revenue-chart-label" class="visually-hidden">Quarterly revenue chart, 2023 shows steady growth</p>
    <div class="chart-thumb" role="img" aria-labelledby="revenue-chart-label"></div>
    
    <!-- Prefer semantic img when possible -->
    <img src="/images/map.png" alt="Store locations across the U.S." />

    Bad Example

    HTML
    <!-- Missing name entirely -->
    <div role="img" class="promo-art"></div>
    
    <!-- Empty label provides no information -->
    <div role="img" aria-label=""></div>
    
    <!-- Invalid: alt on a div is ignored; title alone is unreliable -->
    <div role="img" alt="Team photo" title="Team"></div>
    
    <!-- Broken reference: id does not exist or is display:none and removed from the a11y tree -->
    <div role="img" aria-labelledby="missing-caption"></div>

    Quick Checklist

    • If it’s a real image, use <img> with a meaningful alt.
    • For role="img" on non-image elements, provide aria-label or aria-labelledby.
    • Never leave aria-label empty; avoid whitespace-only values.
    • Ensure aria-labelledby targets exist and are not removed from the accessibility tree.
    • Keep names concise and informative; describe purpose, not just appearance.
    • Hide decorative graphics from assistive tech (aria-hidden="true"), not with role="img".
    • Do not rely on title as the sole accessible name.
    • Verify with a screen reader that the image is announced clearly as a graphic with the intended text.