Tips for Creating Accessible SVG

Share this article

Scalable Vector Graphics (SVG) exists in a quantum state of accessibility. Which is to say that SVG is both accessible and inaccessible at the same time. Happily, there is no SVG uncertainty principle. We know which aspects of SVG are accessible to whom, which are not, and what we can do to improve both. SVG 1.0
was released by the W3C in 2001. SVG 1.1 came along in 2003, and SVG 1.1 2nd edition in 2011. This article looks at ways to make SVG content as accessible as possible. For an introduction on the format and when to use it, please read our SVG guide.

Tip #1: Use SVG

This may seem like a strange thing to say, not least in an article that’s about SVG to begin with. The fact is that one of SVG’s most compelling characteristics is also one of its most accessible. SVG content is scalable, and more to the point it scales without any reduction in visual quality. This makes it extremely versatile from a development point of view, but it also means that people with less than 20/20 vision can enjoy crisp and clear images no matter what screen size and resolution they use.

Tip #2: Use inline SVG

The best way to make SVG accessible to Assistive Technologies (AT) like screen readers and speech recognition tools is to put it directly into your HTML. It’s much cleaner (in code terms) to do this with HTML5 than it was with HTML4.x, because the HTML parser automatically switches mode and puts the SVG elements and attributes into the correct namespace. In other words, if your HTML uses the HTML5 doctype, you don’t need to include a namespace declaration in the <svg> tag.

<svg version="1.1" width="300" height="200">...</svg>
Using other methods to incorporate SVG produces less reliable accessibility results, or limits the information available to AT. For example, SVG content pulled in via the <embed> or <object> elements isn’t as well accessibility supported by browsers as inline SVG, and SVG pulled in via the <img> element is limited in the information that can be exposed to AT. SVG supports DOM 2, so information about the SVG can be programmatically examined and manipulated. Scraping the DOM isn’t an efficient way for AT to obtain information though. It’s much more efficient when information about the DOM is exposed by the browser’s accessibility API. All modern browsers have an accessibility API providing properties and methods that can be queried by AT. For the purposes of this article, we’ll focus on the following browser/screen reader combinations: Internet Explorer 11, Firefox 28 and Chrome 30 on Windows, with Jaws 15 and NVDA 2014.1. Safari 6 on iOS/OSX with VoiceOver, and Chrome 30 on Android with TalkBack. Of these browsers, only IE and Firefox expose the role of the <svg> element through their accessibility API at this time. IE identifies it as a graphic, and Firefox as a diagram. Of the screen readers used with these browsers, only Jaws with IE utilises this information to indicate there is graphical content on the page. The good news is that there is something we can do about that. Hold that thought, we’ll come back to it later on.

Tip #3: Provide a title

The SVG <title>
element provides a human readable name for the SVG content, or a component within it. The <title> element must be the first child of its parent element, which may be one of the SVG container elements or graphics elements, or the <svg> element itself. The SVG 1.1 specification specifically mentions the importance of providing a title for the <svg> element.

<svg version="1.1" width="300" height="200">
<title>Green rectangle</title>
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
</svg>
The content of the <title> element isn’t rendered visually by default (although it can be styled to do so). It should be exposed through the browser’s accessibility API though, specifically to give its parent element an accessible name. In the previous example, the content of the <title> element gives the <svg> element its accessible name, enabling screen readers to differentiate this chunk of SVG content from any other on the page. To put it simply, the <title> element provides an alternative text description of the SVG content. Think of it in the same way you would the alt attribute on the HTML <img> element. At the moment only IE and Firefox correctly expose this information, and only Jaws in IE makes use of it. We can improve these odds though. When ARIA 1.0 is present in the HTML code, it causes the browser to update the information it makes available through its accessibility API. ARIA has good support across browsers and screen readers (although no other AT at this time), so it can help bolster the accessibility of SVG content for blind and partially sighted people. ARIA support is introduced officially into the SVG 2.0 specification, but it is still possible to use ARIA with SVG 1.1 content. Some examples in this article will raise a flag when you validate your HTML, but it’s a reasonable exception to make.

<svg version="1.1" width="300" height="200" aria-labelledby="title">
<title id="title">Green rectangle</title>
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
</svg>
The aria-labelledby attribute in this example re-enforces the relationship between the <svg> and <title> elements. In other words, it ensures the content of the <title> element is recognised as the accessible name for the SVG content. The effect is that now Chrome and Safari also expose “Green rectangle” as the accessible name for the SVG content, and screen readers including VoiceOver, TalkBack, Jaws and NVDA all make use of it in at least one browser.

Tip #4: Provide a description

The SVG <desc> element is similar to the <title> element in many ways. It doesn’t render visually by default, but it is intended for human consumption. Instead of providing a name for its parent element, it provides a description. In accessibility terms, the <desc> element is where you provide more detailed information about the SVG content than the <title> allows.

<svg version="1.1" width="300" height="200">
<title>Green rectangle</title>
<desc>A light green rectangle with rounded corners and a dark green border</desc>
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
</svg>
Browser accessibility support for the <desc> element is about the same as for the <title> element. The content of the <desc> element should be exposed as the accessible description for the containing element, but again only IE and Firefox do the honours. ARIA comes to the rescue here too, but not in the way you might think. The obvious solution should be to use the aria-describedby attribute to –re-enforce the relationship between the <svg> and <desc> elements.

<svg version="1.1" width="300" height="200" aria-labelledby="title" aria-describedby="desc">
<title id="title">Green rectangle</title>
<desc id="desc">A light green rectangle with rounded corners and a dark green border</desc>
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
</svg>
Although the browser’s now expose the correct information through their accessibility API, screen reader support is much less consistent. Jaws and NVDA with IE, VoiceOver with Safari and TalkBack with Chrome all make use of the accessible description, but Jaws and NVDA with Chrome and Firefox do not. For the time being a workaround is to make the aria-labelledby attribute work a little bit harder.

<svg version="1.1" width="300" height="200" aria-labelledby="title desc">
<title id="title">Green rectangle</title>
<desc id="desc">A light green rectangle with rounded corners and a dark green border</desc>
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
</svg>
This isn’t ideal because the name and description are conceptually different things, and serve different purposes. In the interests of making relevant information available as widely as possible this approach does the trick though, albeit through slightly gritted teeth.

Tip #5: Use text

Text is generally accessible however it’s presented, with the exception of raster images (png, jpg etc.). Text in these images can’t be detected by screen readers (or search engines), and it can’t be resized for easier reading comfort. Even when zoomed, the quality of text in images reduces noticeably, and the UX for people with low vision deteriorates right along with it.

<svg version="1.1" width="300" height="200" aria-labelledby="title desc">
<title id="title">Green rectangle</title>
<desc id="desc">A light green rectangle with rounded corners and a dark green border.</desc>
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
<text x="35" y="30" font-size="1em" text-anchor="middle" fill="#000000">Website</text>
</svg>
The SVG <text> element makes text in graphical content highly accessible. The content of the <text> element is rendered as plain text by the browser, so it’s available to screen readers, and because it’s SVG it can be resized proportionately with the graphical content for the benefit of anyone with less than 20/20 vision. You still want to make the default text size comfortable to read, but beyond that people can adjust the SVG to suit themselves.

Tip #6: Make it focusable

If your SVG contains content that is interactive, you’ll need to make sure it can take keyboard focus. As with HTML, the best way to do this is to use an element natively designed to take focus in the first place.

<svg version="1.1" width="300" height="200" aria-labelledby="title desc">
<title id="title">Green rectangle</title>
<desc id="desc">A light green rectangle with rounded corners and a dark green border.</desc>
<a xlink:href="http://example.com">
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
<text x="35" y="30" font-size="1em" text-anchor="middle" fill="#000000">Website</text>
</a>
</svg>
The SVG <a> element should mean that keyboard users can focus on the link when using the tab key to move through the content. All the browser/screen reader combinations mentioned in this article all support that behaviour.

Tip #7: Give it a role

Remember that thought you were holding? We’ve arrived at the point where we can solve the problem of the <svg> element role not being correctly exposed by all browsers. All elements have a role – it identifies the purpose that element fulfils. The role of an element should be exposed through the browser’s accessibility API, but you’ll recall that only IE and Firefox correctly exposed the <svg> element to AT, and only Jaws with IE utilised that information. The ARIA role attribute can be used to force the correct role to be exposed to screen readers. In the case of the <svg> element we can apply the img role.

<svg version="1.1" width="300" height="200" aria-labelledby="title desc" role="img">
<title id="title">Green rectangle</title>
<desc id="desc">A light green rectangle with rounded corners and a dark green border.</desc>
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
</svg>
This improves the browser odds considerably, with IE, Firefox, Chrome and Safari all exposing the role correctly. Screen reader support is still a little inconsistent, but it too improves, with the exception of Jaws and NVDA in Chrome, and Jaws in Firefox. VoiceOver with Safari, TalkBack with Chrome and Jaws and NVDA with IE all now recognise there is graphical content on the page. It may not always be appropriate to use the img role on the <svg> element though. It’s fine if your SVG content is purely graphical, but if it contains interactive content, a different approach may be needed.

<svg version="1.1" width="300" height="200" aria-labelledby="title desc">
<title id="title">Green rectangle</title>
<desc id="desc">A light green rectangle with rounded corners and a dark green border.</desc>
<a xlink:href="http://example.com" tabindex="0" role="link">
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90" stroke="#228b22" stroke-fill="1" />
<text x="35" y="30" font-size="1em" text-anchor="middle" fill="#000000">Website</text>
</a>
</svg>
In this example the link role has been applied to the SVG <a> element. Now all browser/screen reader combinations we’ve looked at in this article recognise that the link is a link, with the exception of NVDA in IE.

Tip #8: Create an alternative

Whilst there is much you can do to bolster SVG accessibility with ARIA, native accessibility support for SVG amongst browsers and AT is still evolving. SVG 2.0 will change this, but for now we need to be realistic about the current state of affairs. When you create something in SVG it’s a good idea to provide the same information and/or functionality in a format that has better accessibility support. If your SVG content is purely graphical in nature, using ARIA to enhance the <title> and <desc> elements will do the trick. If your SVG contains anything more complex or interactive, then you’ll need to think about presenting it in different ways. For example information presented in an SVG graph might also be provided in an HTML table, perhaps with a choice of views offered through a tabbed interface. In some respects, SVG is the forgotten technology of the web. It has enormous practical and creative potential though, and its accessibility potential is just as strong. This article suggests steps you can take to make your SVG 1.1 content more accessible, but the really exciting stuff is coming with SVG 2.0. If you’re interested in helping us make this happen, you can join the W3C Accessible SVG community group, or get involved with the W3C SVG working group.

Frequently Asked Questions (FAQs) on Accessible SVGs

What are the best practices for making SVGs accessible?

To make SVGs accessible, it’s crucial to provide alternative text for the SVG. This can be done using the <title> and tags within the SVG code. The <title> tag provides a short description of the SVG, while the tag provides a more detailed description. Additionally, using ARIA roles and properties can enhance the accessibility of SVGs. For instance, the role=”img” attribute can be used to indicate that the SVG is an image.

How can I make SVG patterns accessible?

SVG patterns can be made accessible by providing a text alternative that describes the pattern. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG patterns. For instance, the role=”img” attribute can be used to indicate that the SVG is an image.

How can I make SVG animations accessible?

SVG animations can be made accessible by providing a text alternative that describes the animation. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG animations. For instance, the role=”img” attribute can be used to indicate that the SVG is an image.

How can I make SVG icons accessible?

SVG icons can be made accessible by providing a text alternative that describes the icon. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG icons. For instance, the role=”img” attribute can be used to indicate that the SVG is an icon.

How can I make SVG graphs and charts accessible?

SVG graphs and charts can be made accessible by providing a text alternative that describes the graph or chart. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG graphs and charts. For instance, the role=”img” attribute can be used to indicate that the SVG is a graph or chart.

How can I make SVG maps accessible?

SVG maps can be made accessible by providing a text alternative that describes the map. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG maps. For instance, the role=”img” attribute can be used to indicate that the SVG is a map.

How can I make SVG logos accessible?

SVG logos can be made accessible by providing a text alternative that describes the logo. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG logos. For instance, the role=”img” attribute can be used to indicate that the SVG is a logo.

How can I make SVG diagrams accessible?

SVG diagrams can be made accessible by providing a text alternative that describes the diagram. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG diagrams. For instance, the role=”img” attribute can be used to indicate that the SVG is a diagram.

How can I make SVG illustrations accessible?

SVG illustrations can be made accessible by providing a text alternative that describes the illustration. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG illustrations. For instance, the role=”img” attribute can be used to indicate that the SVG is an illustration.

How can I make SVG infographics accessible?

SVG infographics can be made accessible by providing a text alternative that describes the infographic. This can be done using the <title> and tags within the SVG code. Additionally, using ARIA roles and properties can enhance the accessibility of SVG infographics. For instance, the role=”img” attribute can be used to indicate that the SVG is an infographic.

Léonie WatsonLéonie Watson
View Author

Léonie Watson is a digital accessibility consultant, member of the W3C HTML Working Group and HTML Accessibility Task Force.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form