cart phone checkmark twitter

Accessible SVGs

Heather Migliorisi

Disclaimer: Everything presented here is my own and does not reflect the views of my employer.

What are SVGs?

Scalable Vector Graphic (SVG) is a generalized graphics markup language

  • icons
  • complex images
  • data visualizations
  • animated pictures
  • interactive applications
See the Pen Responsive Huggy Laser Panda Factory by Sarah Drasner (@sdras) on CodePen.

How does web content work with assitive technology?

Accessibility Tree

Users of assitive technology are not really interacting directly with the page content. They are presented with the page's accessibility tree. Image from WICG AOM

Native Element

Native HTML elements are implicitly mapped to accessibility APIs. For example, an image element will automatically be mapped to an accessibility node with a role of 'image' and a label based on the alt attribute. Image from WICG AOM

ARIA - Accessible Rich Internet Applications

So, ARIA was created by the W3C and it provides a standard that allows developers to set roles, states and properties on html elements so that they can be mapped properly to the Accessibility API.
  • role (checkbox)
  • state (checked)
  • property (e.g. aria-label="label")

Developer Tools

The example you see here is Safari, Chrome and Firefox. Each is inspecting the exact same SVG but  they all map it to a different role. This is important to remember for later.

Quick Detour

Examples tested with latest versions of:

NVDA

  • Chrome
  • Firefox

JAWS

  • Chrome
  • Edge

VoiceOver

  • Safari
  • iOS Safari

Most common browser and screen reader combos: Webaim screen reader survey #9

Real World Examples

So, here we have a fake coffee house brand website. It is themed in a codie/minimalist style and mostly black and white.There's a header with a logo and 3 links with icons + text under them. Underneath the header is a big her promo banner with a bunch text, an image and a button. Then, there's a section of locations with images, addresses and hours of operation. Finally, the footer, with some contact and social info. In terms of SVGs, we have a lot of them here: logo and icons

The Logo

SVG as <img> src - Unlinked

SVG as <img> src - zombie Safari bug

Zombie Safari bug

SVG as <img> src - linked

Inline SVG - unlinked

Inline SVG - unlinked - fixed

Inline SVG - unlinked - title and description

Inline SVG - unlinked - title and description - fixed

Inline SVG - linked - aria-label

Inline SVG - Animation

Inline SVG - Animation

screenshot of codepen showing the css and javasript options for handling reduced motion settings

Next Example: Icons

There are a bunch of icons used in this site (the location, coffee beans and cart links in the header, phone and twitter icons in the footer) AND almost each one is implemented in a different way because they have a different context on the page.

Icon - decorative - linked, not linked and button

Icon - content - not linked

Icon - content - linked

Icon - content - linked

Icon - content - linked + text

Icon - content - button

Final Example

Screenshot of the site page again, this time with the promo banner circled.

<Text> is Traversable!!!

Screenshot of a codepen with just the hero image in it and the top of the svg code showing in the html

Semantics

Screenshot of a codepen with just the hero image in it and html showing that role=link was added to anchor

:focus Styles

Screenshot of a codepen with just the hero image in it, the link/button with the focus styling and the css for the focus styling

Semantics - continued

Screenshot of a codepen with just the hero image in it and html showing that role=link was added to anchor

Hide the Decorative Image

Screenshot of a codepen with just the hero image in it and html showing that aria-hidden added to the image

Final Result

NVDA + Firefox

Forgetting Something

SVGs and High Contrast Mode

Ok, so viewing the site in Widows high contrast mode shows that the logo and all of the icons have disappeared into the black background and need fixed. On the bright side, since the hero image had a white rectangular box behind the text, it is readable. We should probably take that same approach with the logo (to ensure branding stays intact).

Add a shape to the background

adding a color filled (in this case white) box behind the black text allows us to maintain the desired design of the logo.

Media queries and currentColor

Now, for the icons, we'll need to use the media query for forced colors.

currentColor

Inside the media query, I also thought it would be great if something like currentColor would work for the fills/strokes because we could add a few simple lines and be done. long story short...This is going to change back in browsers because the spec has been revised to reflect the previous desired behavior of currentColor.

Use System Colors

For now, we can use sytem colors to ensure things look the way they should. System Colors

Take Aways...

Take aways:

  1. hide decorative images from screen readers aria-hidden="true"
  2. provide meaningful alternative text for content images
  3. add roles to elements to ensure they map properly to the Accessibility API
  4. provide :focus styles for actionable elements
  5. make sure images are not lost in high contrast

Test early, test often!

  • with various screen readers + browsers
  • different contrast modes
  • keyboard navigation
  • with real users

Finally

Resources and Further Reading

Twitter @_hmig