Deeper Dive on Accessible SVG Patterns

Featuring twelve SVG pattern examples and screen reader tests!

Originally published on Deque Systems

January 10, 2019

SVG All the Things!

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 125 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

Lightbulb drawing painted in coral color.

Code

<img class="lightbulb" alt="Lightbulb moment!" src="https://upload.wikimedia.org/wikipedia/commons/2/2b/BulbIcon.svg">

SVG Pattern 2

Lightbulb drawing painted in purple color.

Code

<img class="lightbulb" role="img" src="https://upload.wikimedia.org/wikipedia/commons/2/2b/BulbIcon.svg" alt="Lightbulb moment!" />

SVG Pattern 3

Lightbulb drawing painted in rose color.

Code

<img class="lightbulb" role="img" src="https://upload.wikimedia.org/wikipedia/commons/2/2b/BulbIcon.svg" aria-label="Lightbulb moment!" />

SVG Pattern 4

Lightbulb drawing painted in lime-green color.

Code

<p id="caption1" class="visually-hidden">Lightbulb moment!

<img class="lightbulb" role="img" src="https://upload.wikimedia.org/wikipedia/commons/2/2b/BulbIcon.svg" aria-labelledby="caption1" />

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

Lightbulb drawing painted in dark blue color.

Code

<svg role="img" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve"> <title>Lightbulb moment!</title> <path d="M19..."/> </svg>

SVG Pattern 6

Lightbulb drawing painted in dark green color.

Code

<svg role="img" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve"> <text>Lightbulb moment!</text> <path d="M19..."/> </svg>

SVG Pattern 7

Lightbulb drawing painted in dark purple color.

Code

<svg role="img" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve"> <title>Lightbulb moment!</title> <text class="visually-hidden" font-size="0">I have a great idea.</text> <path d="M19..."/> </svg>

SVG Pattern 8

Lightbulb drawing painted in baby pink color.

Code

<svg role="img" aria-labelledby="lightbulb8" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve"> <title id="lightbulb8">Lightbulb moment!</title> <path d="M19..."/> </svg>

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)

SVG Pattern 9

Lightbulb drawing painted in orange color.

Code

<svg role="img" aria-describedby="lightbulb9" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve"> <title id="lightbulb9">Lightbulb moment!</title> <path d="M19..."/> </svg>

SVG Pattern 10

Lightbulb drawing painted in baby blue color.

Code

<svg role="img" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve"> <title>Lightbulb moment!</title> <desc>I have a great idea.</desc> <path d="M19..."/> </svg>

SVG Pattern 11

Lightbulb drawing painted in hot pink color.

Code

<svg role="img" aria-labelledby="lightbulb11 description11" version="1.1" class="hotpink" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve"> <title id="lightbulb11">Lightbulb moment!</title> <desc id="description11">I have a great idea.</desc> <path d="M19..."/> </svg>

SVG Pattern 12

Lightbulb drawing painted in gray color.

Code

<svg role="img" aria-describedby="lightbulb12 description12" version="1.1" class="ltgray" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve"> <title id="lightbulb12">Lightbulb moment!</title> <desc id="description12">I have a great idea.</desc> <path d="M19..."/> </svg>

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


Creating accessible SVGs banner.

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!