SVG Accessibility: What Screen Reader Testing Reveals
Scalable Vector Graphics have evolved far beyond simple display images. Thanks to JavaScript and CSS media queries, SVGs now power interactive elements, animated icons, and responsive visuals across the web. But as our usage expands, so does the responsibility to make these graphics accessible to all users, including those relying on screen readers.
The challenge is that the same SVG markup can produce wildly different announcements depending on the operating system, browser, and screen reader combination. To clarify the landscape, we examined twelve distinct SVG patterns found in production websites, documenting how assistive technology interprets each one.
External SVG Files: The <img> Tag Approach
The first group of patterns uses the HTML <img> tag to reference external SVG files. This approach keeps the markup clean and often results in faster page loads. It does, however, limit your control over internal SVG elements and animations.
Pattern 1: <img> + alt="[words]"
This is the most straightforward pattern—treating the SVG just like any other image with alternative text. Unfortunately, test results show that this pattern is unreliable.
<img class="fox" alt="What does the fox say?" src="https://upload.wikimedia.org/wikipedia/commons/3/39/Toicon-icon-fandom-howl.svg">
Pattern 2: <img> + role="img" + alt="[words]"
Adding an explicit role="img" alongside the alt attribute produces consistent results across most modern screen readers and browsers.
<img role="img" class="fox" alt="What does the fox say?" src="https://upload.wikimedia.org/wikipedia/commons/3/39/Toicon-icon-fandom-howl.svg">
Pattern 3: <img> + role="img" + aria-label="[words]"
If you prefer using aria-label over alt, this pattern demonstrates that it can work equally well when paired with role="img".
<img role="img" class="fox" aria-label="What does the fox say?" src="https://upload.wikimedia.org/wikipedia/commons/3/39/Toicon-icon-fandom-howl.svg">
Pattern 4: <img> + role="img" + aria-labelledby="[ID]"
Referencing an external text element via aria-labelledby adds complexity, and with it, variability in how different screen readers handle the reference.
<p id="caption1" class="visually-hidden">What does the fox say?</p>
<img role="img" aria-labelledby="caption1" class="fox" src="https://upload.wikimedia.org/wikipedia/commons/3/39/Toicon-icon-fandom-howl.svg">
Inline SVG Markup: Deep Control, Deeper Testing
The second set of patterns moves the SVG code directly into the HTML. This increases control over individual elements and allows for a variety of accessibility techniques, but it also introduces a wider range of possible assistive technology interpretations.
Pattern 5: <svg> + role="img" + <title>
A simple nested <title> element works well as a concise name for the graphic when combined with a role of img. This is a solid baseline pattern.
<svg role="img" ...>
<title>What does the fox say?</title>
[design code]
</svg>
Pattern 6: <svg> + role="img" + <text>
Spelling out the description in literal SVG <text> might seem helpful, but this pattern fails. Any text not referencing the right native SVG structure gets announced inconsistently. This is one to avoid.
<svg role="img" ...>
<text class="visually-hidden" font-size="0">What does the fox say?</text>
[design code]
</svg>
Pattern 7: <svg> + role="img" + <title> + aria-describedby="[ID]"
Connecting a separate description to the title complicates the announcement order and leads to some screen readers dropping crucial information.
<svg role="img" aria-describedby="fox7" ...>
<title id="fox7">What does the fox say?</title>
[design code]
</svg>
Pattern 8: <svg> + role="img" + <title> + aria-labelledby="[ID]"
This paired approach uses aria-labelledby to point to the title as the accessible name, resulting in strong and consistent performance across the test board.
<svg role="img" aria-labelledby="fox8" ...>
<title id="fox8">What does the fox say?</title>
[design code]
</svg>
Handling Complex Graphics with Extended Descriptions
The final group covers inline SVG patterns meant for detailed charts, diagrams, or data visualizations that require an extended explanation. Relying on these patterns alone might not be user-friendly for someone with cognitive disabilities; having the explanation on the visible page can be a better alternative.
Pattern 9: <svg> + role="img" + <title> + <text>
When a short title is accompanied by a printed <text> explanation, some screen readers either ignore the extended portion or combine them awkwardly.
<svg role="img" ...>
<title>What does the fox say?</title>
<text class="visually-hidden" font-size="0">Will we ever know?</text>
[design code]
</svg>
Pattern 10: <svg> + role="img" + <title> + <desc>
The native SVG <desc> element is the intended vehicle for long descriptions. Pairing it with a <title> can be hit or miss; several screen readers choose to ignore the description entirely.
<svg role="img" ...>
<title>What does the fox say?</title>
<desc>Will we ever know?</desc>
[design code]
</svg>
Pattern 11: <svg> + role="img" + <title> + <desc> + aria-labelledby="[ID]"
Assigning the accessible name via aria-labelledby to include both the title and the description ensures that nothing is skipped. Although this can lead to every element being announced—and sometimes repeated—the thoroughness of this method appears to outweigh its flaws.
<svg role="img" aria-labelledby="fox11 description11" ...>
<title id="fox11">What does the fox say?</title>
<desc id="description11">Will we ever know?</desc>
[design code]
</svg>
Pattern 12: <svg> + role="img" + <title> + <desc> + aria-describedby="[ID]"
Moving the attribution to aria-describedby reverses the trend and creates inconsistency in many instances, making the long description get completely missed by common users.
<svg role="img" aria-describedby="fox12 description12" ...>
<title id="fox12">What does the fox say?</title>
<desc id="description12">Will we ever know?</desc>
[design code]
</svg>
Results: Which Patterns Win
The testing table reveals clear winners and losers, with several middle-ground patterns that you can use if you are mindful of their limitations. Keep in mind that every pattern was tested across multiple OS, browser, and screen reader setups.
External <img> Group
- Pattern 2 (
<img>+role="img"+alt="[words]") is the safest bet for this group. - Pattern 3 (
<img>+role="img"+aria-label="[words]") also performs exceptionally well. - Pattern 4 (
<img>+ externalaria-labelledby) should be used with caution. - Pattern 1 (plain
altattribute) is not recommended; testing shows assistive technology often fails to announce it as an image.
Basic Inline SVG Group
- Pattern 5 (
role="img"+<title>) and Pattern 8 (addingaria-labelledby) both earned “Best In Show.” - Pattern 7 (
aria-describedbyfor the title) is less consistent—use with caution. - Pattern 6 (with embedded
<text>) is not recommended.
Extended Description Inline SVG Group
- Pattern 11 (
<title>+<desc>+aria-labelledby) is the sole winner in this group. Even though descriptions were sometimes repeated, all elements were always recognized and announced. - Patterns 9, 10, and 12 fall squarely in the “use caution” camp. Their tests routinely missed the description text.
Beyond Pattern Tests: Recommended Reading
Navigating screen reader compatibility introduces complications. Part of the variability stems from screen reader developers officially supporting certain browser pairings, but fringe combinations still need consideration for real-world usage.
Before deciding on a pattern, ensure you understand the fundamentals of creating accessible images and the requirements for different image context. For additional help matching the right solution to your environment, review this analysis of other accessible pattern choices.
With a firm grasp of these patterns and their outcomes, your SVGs can communicate their purpose effectively to everyone.
See the Pen [Testing Results](https://codepen.io/smashingmag/pen/YzZQBwG) by Carie Fisher.



