Illustration with the text Creating Accessible SVGs with img and svg tags

Creating Accessible SVGs

Scalable Vector Graphics (SVGs) have been around since 1999, but they have seen a real resurgence in use as design interactions have become more complex and CSS/JavaScript have replaced antiquated animation programs such as Adobe Flash. There are plenty of reasons to use SVGs today including:

  • Browser support – Increased native browser support of SVGs means better consistency and higher fidelity of images.
  • Code control – Advancements in CSS and JavaScript functionality to style and animate images.
  • File size – The relative “lightness” of SVG code in a world where bandwidth and performance matter more than ever.
  • Accessibility – Markup can be added to the SVGs directly so more information can be added within the image itself – which is helpful for people using assistive technology devices such as screen readers.

Of course, this article will be focusing on accessibility, but it is good to know there are a lot of other benefits to using SVGs (just in case someone needs more convincing).

Basic Accessibility Rules for Images

Before we get to SVG accessibility you need to think about the purpose of your image. Is it to inform a user? Set the “mood” of the site? Enhance a call-to-action button? It is important to identify which of your images are decorative and which are informative. This is not always an easy task.

If an image is decorative, it needs to have an empty/null alternative text attribute. This sends a signal to the assistive technology devices (ATs) to ignore this image as it is not necessary for understanding the content or action on the page. An empty/null alternative text attribute is not the same as a missing alternative text attribute. If the alternative text attribute is missing, the AT might read out the file name or surrounding content in an attempt to give the user more information about the image.

If an image is informative, first make sure it meets WCAG standards for color contrast. There are many color contrast tools out there to help you with this task. Next, make sure you include alternative information about the image. As a reminder, alternative content needs to be meaningful and descriptive, should not exceed 250 characters, and should be unique. Make sure you avoid phrases like “image of” or “graphic of” to describe an image. A screen reader already tells the user this information.

In addition to the basic image rules, there are some SVG specific things to consider:

  • SVGs cannot flash or blink at a rate of three times per second or more. For some users, flashing or blinking content can trigger a seizure. This is serious stuff. Use the free Photosensitive Epilepsy Analysis Tool (PEAT) to test any content that could be problematic.
  • SVG animations must not auto-play for more than five seconds. If you plan to have SVG animations go on longer than 5 seconds or play on an infinite loop, you must create a way for users to pause the animation. An animation that cannot be paused can be extremely distracting for people with cognitive disabilities.
  • Not all SVGs are created equal. There are a few older/mobile browsers have issues with some SVG specific elements like <use>. And elements such as <iframe> or <object> may render fine in most browsers but may have poor AT support. But have no fear –  there are always fallback options, workarounds, and polyfills available if needed.

Accessible Patterns for SVGs

Now that we have some basics out of the way, let’s talk patterns! Over the years I have seen and used a lot of different patterns to add additional descriptive content to SVGs. But it was unclear which of these options was the best to use for the most coverage of browsers and screen readers. There are articles that touch on the subject, but many are dated or do not cover all of the patterns available, so I decided to do my own high-level browser/screen reader testing.

The methodology was straight-forward. First, I researched some popular patterns and recreated them using a non-animated open-source SVG from WikiCommons. For each SVG pattern, I added the phrase “Lightbulb moment!” as the main alternative content for the image, followed by the phrase “I have a great idea” in the patterns that allowed for more descriptive content. Then I tested each pattern using the specific browser/screen reader combinations recommended by Deque. The final results are shown in the tables below.

Note: Due to formatting restraints, I had to break up the results into multiple tables for this article. To see all of the patterns and results in one place, see the complete CodePen here: (https://codepen.io/cariefisher/pen/bOKEVQ).

Using the <img> Tag

For basic, uncomplicated, or decorative images, use the <img> tag and reference the SVG as a file. This pattern should render lighter and faster pages overall (versus inline SVGs) and allow for easier maintenance on SVGs that you use in multiple places.

SVG Pattern 1

<img> + alt="[words]"

Code:

SVG pattern 2

<img> + role="img" + alt="[words]"

Code:

SVG pattern 3

<img> + role="img" + aria-label="[words]"

Code:

SVG pattern 4

<img> + role="img" + aria-labelledby="[ID]"

Code:

Results for SVG Patterns using <img>

Screen Reader + BrowserPattern 1Pattern 2Pattern 3Pattern 4
Mac: Safari + VoiceOver
(v 12.0.2)
Lightbulb Moment! (group)Lightbulb Moment! (image)Lightbulb Moment! (image)Lightbulb Moment! Lightbulb Moment! (image)
Windows: Firefox + NVDA
(FF v63.0.1 + NVDA v2018.4)
(graphic) Lightbulb moment!(graphic) Lightbulb moment!(graphic) Lightbulb moment!Lightbulb moment! (graphic) Lightbulb moment!
Windows: Chrome + NVDA
(Chrome v71.0 + NVDA v2018.1.1)
(graphic) Lightbulb moment!(graphic) Lightbulb moment!(graphic) Lightbulb moment!Lightbulb moment! (graphic) Lightbulb moment!
Windows: Edge + Narrator
(v42.17134)
(image) Lightbulb moment!(image) Lightbulb moment!(image) Lightbulb moment!Lightbulb moment! (image) Lightbulb moment!
Windows: IE11 + JAWS
(IE 11 v11.111 + JAWS Prof 2018)
(graphic) Lightbulb moment!(graphic) Lightbulb moment!(graphic) Lightbulb moment!Lightbulb moment! (graphic) Lightbulb moment!
Mobile (iOS): Safari + VoiceOver
(v12.1.2)
Not focusableLightbulb Moment! (image)Lightbulb Moment! (image)Lightbulb Moment! Lightbulb Moment! (image)
Mobile (Android): Chrome + TalkBack
(Google Pixel 2 + Android v9)
Lightbulb moment! (graphic)Lightbulb moment! (graphic)Lightbulb moment! (graphic)Lightbulb moment! Lightbulb moment! (graphic)
Mobile (Android): Firefox + TalkBack
(Google Pixel 2 + Android v9)
Lightbulb moment! (graphic)Lightbulb moment! (graphic)Lightbulb moment! (graphic)Lightbulb moment! (graphic)

 

Using the <svg> Tag

For more complex or essential SVGs, you should consider adding the SVG as markup into the HTML. Although adding the SVG into the markup makes the page potentially heavier and slower, you have more options with JavaScript and CSS to manipulate the styles and animations of the images.

SVG pattern 5

<svg> + role="img" + <title>

Code:

 

SVG pattern 6

<svg> + role="img" + <text>

Code:

 

SVG pattern 7

<svg> + role="img" + <title> + <text>

Code:

 

SVG pattern 8

<svg> + role="img" + <title> + aria-labelledby="[ID]"

Code:

 

SVG pattern 9

<svg> + role="img" + <title> + aria-describedby="[ID]"

Code:

 

SVG pattern 10

<svg> + role="img" + <title> + <desc>

Code:

 

SVG pattern 11

<svg> + role="img" + <title> + <desc> + aria-labelledby="[ID]"

Code:

 

SVG pattern 12

<svg> + role="img" + <title> + <desc> + aria-describedby="[ID]"

Code:

 

Results for SVG Patterns using <svg>

Screen Reader + BrowserPattern 5Pattern 6Pattern 7Pattern 8
Mac: Safari + VoiceOver (v 12.0.2)Lightbulb Moment! (image)Lightbulb Moment!I have a great idea.

<title> ignored

Lightbulb Moment! (image)
Windows: Firefox + NVDA (FF v63.0.1 + NVDA v2018.4)Lightbulb moment! (graphic) Lightbulb moment!Not focusableLightbulb moment! (graphic) Lightbulb moment!

<text> ignored

Lightbulb moment! (graphic) Lightbulb moment!
Windows: Chrome + NVDA (Chrome v71.0 + NVDA v2018.1.1)(graphic) Lightbulb moment!Not focusable(graphic) Lightbulb moment!

<text> ignored

(graphic) Lightbulb moment!
Windows: Edge + Narrator (v42.17134)(image) Lightbulb moment!(image) Lightbulb moment!(image) Lightbulb moment! I have a great idea.(image) Lightbulb moment!
Windows: IE11 + JAWS (IE 11 v11.111 + JAWS Prof 2018)(graphic) Lightbulb moment!(graphic) Lightbulb moment!(graphic) Lightbulb moment! (graphic) I have a great idea.(graphic) Lightbulb moment!
Mobile (iOS): Safari + VoiceOver (v12.1.2)Lightbulb Moment! (image)(image)Lightbulb Moment! (image)

<text> ignored

Lightbulb Moment! (image)
Mobile (Android): Chrome + TalkBack (Google Pixel 2 + Android v9)Lightbulb moment! (graphic)Not focusableLightbulb moment! (graphic)

<text> ignored

Lightbulb moment! (graphic)
Mobile (Android): Firefox + TalkBack (Google Pixel 2 + Android v9)Lightbulb moment! (graphic) (graphic)(graphic) Lightbulb moment! (graphic)Lightbulb moment! (graphic) I have a great idea. (graphic)Lightbulb moment! (graphic) (graphic)
Screen Reader + BrowserPattern 9Pattern 10Pattern 11Pattern 12
Mac: Safari + VoiceOver (v 12.0.2)Lightbulb Moment! (image)Lightbulb Moment! (image) I have a great idea.Lightbulb Moment! I have a great idea. (image) I have a great idea.Lightbulb Moment! (image) Lightbulb Moment! I have a great idea.
Windows: Firefox + NVDA (FF v63.0.1 + NVDA v2018.4)Lightbulb moment! (graphic) Lightbulb moment!Lightbulb moment! (graphic) Lightbulb moment!

<desc> ignored

Lightbulb Moment! I have a great idea. (graphic) Lightbulb Moment! I have a great idea.Lightbulb moment! (graphic) Lightbulb moment!

<desc> ignored

Windows: Chrome + NVDA (Chrome v71.0 + NVDA v2018.1.1)(graphic) Lightbulb moment!(graphic) Lightbulb moment!

<desc> ignored

(graphic) Lightbulb Moment! I have a great idea.(graphic) Lightbulb moment!

<desc> ignored

Windows: Edge + Narrator (v42.17134)(image) Lightbulb moment!(image) Lightbulb moment!

<desc> ignored

(image) Lightbulb moment!

<desc> ignored

(image) Lightbulb moment!

<desc> ignored

Windows: IE11 + JAWS (IE 11 v11.111 + JAWS Prof 2018)(graphic) Lightbulb moment!(graphic) Lightbulb moment! (graphic) I have a great idea.(graphic) Lightbulb moment! (graphic) I have a great idea.(graphic) Lightbulb moment! (graphic) I have a great idea.
Mobile (iOS): Safari + VoiceOver (v12.1.2)Lightbulb Moment! (image)Lightbulb Moment! (image) I have a great idea.Lightbulb Moment! I have a great idea. (image) I have a great idea.Lightbulb Moment! (image) Lightbulb Moment! I have a great idea.
Mobile (Android): Chrome + TalkBack (Google Pixel 2 + Android v9)Lightbulb moment! (graphic) Lightbulb moment!Lightbulb moment! (graphic)

<desc> ignored

Lightbulb moment! I have a great idea. (graphic)Lightbulb moment! (graphic) Lightbulb moment! I have a great idea.
Mobile (Android): Firefox + TalkBack (Google Pixel 2 + Android v9)Lightbulb moment! (graphic) (graphic)Lightbulb moment! (graphic) (graphic)

<desc> ignored

Lightbulb moment! I have a great idea. (graphic) (graphic)Lightbulb moment! (graphic) (graphic)

<desc> ignored

SVG Pattern Test Results

Results time! As shown in the tables, there were a few patterns that were not clean and caused the screen reader to repeat the alternative content. And while certainly annoying to users, it is better to hear duplicate content than none at all. Other patterns were much more problematic. For example, pattern 7 was missing the <title> or the <text> element for many browser/screen reader combinations. Likewise, pattern 10 was often missing the <desc> element. Worse still was pattern 6 which caused major issues, like not being able to even focus on the image, with NVDA and some mobile screen readers. For best AT coverage, it is probably best to avoid those three patterns until there is more support for them.

On the flip side, there was no clear frontrunner for “best in show” for the different patterns when relaying basic alternative content. This is actually good news! Since many of the patterns were able to render the alt content, that equates to more pattern choices for designers and developers. For SVGs needing more descriptive alternative content, pattern 11 <svg> + role="img" + <title> + <desc> + aria-labelledby="[ID]" was the most reliable choice for the different browser and screen readers that were tested.

Based on these results, it is clear that not all SVG patterns are created equal when it comes to accessibility. Which pattern you choose to implement depends on many factors like how difficult it is to modify baked-in framework code and which browsers/screen readers you are targeting. But no matter which pattern you choose to use, be sure to set aside some time to do your own accessibility/user testing. As SVGs continue to dominate the visual world, it is important not to leave AT users in the dark!

update selasa

Comments 5 responses

  1. Thanks so much for all the research that went into this article. Invaluable information!

  2. Hi, I have a question about intentionally hiding SVG text from screen readers.

    I am using the desc node to fully describe the image, but what the image has is a geek girl holding a beer and behind her is a wall of XML code.

    What the XML code is is not important, in fact it is light gray on a white background so it would fail contrast tests if it was important. Much of it is blocked by the image of the geek girl, but it is typeset in the SVG node using text nodes to avoid it looking blurry when scaled.

    What I want to avoid is screen readers reading those text nodes to users.

    I am hoping aria-role=”img” along with a title and desc and aria-describedby attribute are enough, but I am wondering if there is another step I should take to tell screen readers the content of those text nodes is not to be read.

    Thank you so much for this article.

  3. Hi Carie,

    Thank you for this interesting article! I have a question:
    What’s the purpose of an image role on an image element like so:

    Greetings,
    John

  4. It would be interesting to have an example where the SVG contains text in a tspan element.

    Is it necessary to copy the text into a separate description, or is it already available for AT?

    I enjoyed the article and it gave me a good sense of what the current technology is.

Leave a Reply

Your email address will not be published. Required fields are marked *