Accessible SVGs: Inclusiveness Beyond Patterns

About The Author

Carie Fisher is an author, speaker, and developer who is passionate about the intersection of front-end code and UX, digital accessibility, and diversity in … More about Carie ↬

Email Newsletter

Weekly tips on front-end & UX.
Trusted by 176.000 folks.

Quick summary ↬ We are fortunate to have robust patterns to choose from when optimizing accessibility in SVGs — but most people stop there, focusing on code compliance and not actual users and their needs. If true inclusiveness lies beyond patterns — what other factors should we consider when designing and developing accessible SVGs?

Scalable Vector Graphics (SVGs) became a W3C open standard in 1999 — back when the new tech hotness was the Blackberry phone, Napster first invaded college dorms, and the Y2K bug sparked fear in us all. Fast forward to our modern digital world and you’ll notice that while the other tech trends have waned, SVGs are still around and thriving.

This is partly due to SVGs having a small footprint for such high visual fidelity, in a world where bandwidth and performance matter more than ever — especially on mobile devices and situations/locations where data is at a premium. But also because SVGs are so flexible with their integrated styles, interactivity, and animation options. What we can do with SVGs today goes way beyond the basic shapes of yesteryear.

If we focus on the accessibility aspect of SVGs, we have come a long way as well. Today, we have many robust patterns and techniques to help us optimize inclusiveness. This is true regardless if you are creating icons, simple images, or more complex images.

While the specific pattern you decide to use might vary depending on your particular situation and targeted WCAG conformance level — the reality is, most people stop there, focusing on code compliance and not actual end-users and their needs. If true inclusiveness lies beyond patterns — what other factors should we consider when designing and developing accessible SVGs?

Styling And Animating SVGs With CSS

Why is it so important to optimize your SVGs? Also, why even put in the effort to make them accessible? Sara Soueidan explais why and also how to style and animate with CSS. Read a related article →

SVG Color And Contrast

The primary focus of accessible SVGs is screen readers compliance — which is only part of the issue and part of the solution. Globally, people with low-vision and color blindness outnumber the people who are blind 14:1. We are talking a staggering 546 million in total (246 million low-vision users plus 300 million colorblind users) vs. 39 million users who are legally blind. Many people with low-vision and colorblindness do not rely on screen readers, but may instead use tools like browser resizing, customized stylesheets, or magnification software to help them see what is on the screen. To these 546 million people, screen reader output is probably not as important to them as making sure the color and contrast is great enough that they can see the SVG on the screen — but how do we go about checking for this?

Tools And Checks

The very first step you should take when designing your SVG color palette is to review the WCAG color contrast ratio guidelines. While SVGs and other icons were exempt from color contrast ratio requirements not too long ago (when targeting WCAG AA compliance), the recent update to the WCAG 2.1 guidelines have made it so all essential non-text imagery must adhere to a contrast ratio of at least 3:1 against adjacent colors. By essential, it means if your SVG was to vanish, would it fundamentally change the information or functionality of the content? If you can answer “no,” then you are likely exempt from this guideline. If you can answer “yes” or “maybe,” then you need to make sure your SVG color contrast ratios are in check.

House icon used in demo with light outline vs dark outline
House icon used in demo with light outline vs dark outline — which is more accessible? (

As with other media queries, to see the light/dark theme changes, the website or app developer must add additional code targeting the query. Going back to the house icon example from earlier, you can see in the following code that the SVG’s stroke, fill, and background colors are controlled by the CSS. Since these style elements are externally controlled and not hard-coded in the SVG markup, we can add a few extra lines of CSS to make the SVG work in a dark theme.

Light/default mode:

House icon used in demo with a light background
House icon used in demo with a light background (Large preview)
body {
  background: #cccccc;
}

.nav-home1 {
  stroke: #8f8f8f;
}

.nav-home2 {
  stroke: #717171;
}

#home-svg1,
#home-svg2 {
  fill: #64b700;
}

#home-door-svg1,
#home-door-svg2 {
  fill: #b426ff;
}

Dark mode:

House icon used in demo with a dark background
House icon used in demo with a dark background (Large preview)
@media (prefers-color-scheme: dark) {

  body {
    background: #333333;
  }

  .nav-home1 {
    stroke: #606060;
  }

  .nav-home2 {
    stroke: #7C7C7C;
  }
}

See the Pen Light/Dark mode with SVGs by Carie Fisher.

See the Pen Light/Dark mode with SVGs by Carie Fisher.

As this example shows, setting up your designs to use CSS to control style elements means that creating a dark theme version of your SVG can be relatively simple. Conversely, if you have hard-coded styles into the SVG markup, you may need to reimagine your SVG in a way that allows CSS to have more control over the design. Or you may want to consider creating a completely new dark version of your SVG and swap out the light version when the theme preferences change. Just remember, if you do plan to show/hide different images based on the user mode, you also need to hide the nonvisible SVG from AT users!

Note: in this particular example, the default theme was already light so it made sense to also make that the default experience and build a dark theme for an alternate experience. Otherwise, if we started with a dark theme, we could have done the opposite making the dark theme the default experience and using @media (prefers-color-scheme: light) to create a light theme.

In the next example, we are looking at a more complex SVG with both light and dark mode versions via the @prefers-color-scheme media query. Our friend Karma Chameleon (in SVG form) has both a dark theme and a light/default theme. By changing your light/dark preference settings (Mac OS + Win OS dark mode settings) and navigating to a browser that supports @prefers-color-scheme media query, you can see the environment change. In the light/default mode, Karma Chameleon is sitting on a branch in a green forest surrounded by a fluttering red butterfly. In dark mode, she is sitting on a branch in space with a blue rocket zooming past. In both environments, her colors automatically change and her eyes move around.

See the Pen [Light/Dark mode + reduced motion with SVGs (Karma Chameleon)](http://codepen.io/smashingmag/pen/rNVJyoj) by Carie Fisher.

See the Pen Light/Dark mode + reduced motion with SVGs (Karma Chameleon) by Carie Fisher.
In the light/default mode, Karma Chameleon is sitting on a branch in a green forest surrounded by a fluttering red butterfly. In both environments, her colors automatically change and her eyes move around.
Karma Chameleon in light mode. (Large preview)
In dark mode, she is sitting on a branch in space with a blue rocket zooming past. In both environments, her colors automatically change and her eyes move around.
Karma Chameleon in dark mode. () and — so this media query is useful out of the box today and it should be sticking around for awhile. Plus with the recent changes to MS Edge using Chromium under the hood, there is even more support for this media query going forward (R.I.P. -ms-high-contrast-mode).
Graph showing which browsers utilize the CSS at-rule: @media: prefers-color-scheme media feature - IE and Opera mobile being the only major non-supporting browsers at this time.
Graph showing which browsers utilize the CSS at-rule: @media: prefers-color-scheme media feature. ( when viewing content that flashes or is bright — a situation you obviously want to avoid.

Manual/Auto Stop

Since SVG animations, like other moving content, must not auto-play for more than five seconds, you must create a way for users to pause or stop the animation. One way to do this is to create a JS toggle button to play/pause the animation.

If your SVG is large or is the main feature of your website (e.g. animations that pop in and out as you scroll down a page) a pause/play button at the top of the screen might be a realistic option to control the entire experience of the page. If your SVGs are smaller in scale or related to user input (e.g. an animation happens when a user submits a form), a pause/play button might not be realistic for each individual image, so an alternative option is to code the animation to stop at five seconds vs. playing it on an infinite loop. ### Reduced Motion

In addition to using a pause/play option or creating a finite animation loop, you may also consider adding @prefers-reduced-motion media query to address the animation in your SVGs. Similar to the light/dark theme example, the @prefers-reduced-motion media query checks the user’s settings for motion restrictions and then implements a visual experience based on their preference. In the case of @prefers-reduced-motion, a user can choose to minimize the amount of animation or motion they see.

In the following example, the animated SVG “writes out” a word as the page loads — this is its default animation. In the reduced motion version, the SVG is stationary and the word loads without the animation. Depending on the complexity of your SVG animation and how you want the reduced motion experience to look, the amount of extra code involved can vary.

See the Pen [Reduced motion with SVGs](http://codepen.io/smashingmag/pen/dyodvqm) by Carie Fisher.

See the Pen Reduced motion with SVGs by Carie Fisher.

Default motion:

Movie depicting text being written out via code not adhering to WCAG best practices on movement
The default motion version of the text script (Large preview)
.svg-color {
  stroke: #ff4b00;
}

#a11y-svg {
  stroke-linecap: round;
  padding: 0.25rem;
  stroke-dasharray: 1000;
  stroke-dashoffset: 0;
  -webkit-animation: dash 5s linear forwards;
  animation: dash 5s linear forwards;
  overflow: visible;
  font-size: 100px;
  height: 0;
  margin: 10rem 0 5rem;
  position: relative;
}

#a11y-svg-design {
  cursor: pointer;
  stroke-width: 2px;
}

@-webkit-keyframes dash {
  from {
    stroke-dashoffset: 1000;
    fill: transparent;
  }

  to {
    stroke-dashoffset: 0;
    fill: #ff4b00;
  }
}

Reduced motion:

Still screenshot of the word accessibility in orange with no movement.
The reduced motion version of the text script. (Large preview)
@media (prefers-reduced-motion: reduce) {
  #a11y-svg {
    animation: none;
    fill: #ff4b00;
  }
}

Keep in mind, having @prefers-reduced-motion code in place is one step in making your SVGs more accessible, but you also need to consider the way the motion is reduced. For example, let’s say you create a slowed-down version of your SVG animation using @prefers-reduced-motion. However, the slower version is on an infinite loop so the animation lasts more than five seconds, which violates one part of the WCAG rules on motion. If you instead create a reduced motion version of your animated SVG that stops the animation at five seconds, then it would pass that part of the rule. This subtle code change equals two completely different user experiences.

In the next example, Karma Chameleon is back with a @prefers-reduced-motion media query and related code. By changing your motion settings (Mac, Win, Android, and iOS settings) and using a browser that supports @prefers-reduced-motion media query, you can see the animation change. In the light mode with reduced motion, Karma Chameleon in a forest with a stationary red butterfly. In dark mode with reduced motion, she is in space with a stationary blue rocket in the background. In both environments, her colors and eyes are also stationary, as the original SVG animation is completely removed.

See the Pen [Light/Dark mode + reduced motion with SVGs (Karma Chameleon)](http://codepen.io/smashingmag/pen/rNVJyoj) by Carie Fisher.

See the Pen Light/Dark mode + reduced motion with SVGs (Karma Chameleon) by Carie Fisher.
In light mode + reduced motion, Karma Chameleon is in a forest with a stationary red butterfly. In both environments, her colors and eyes are also stationary, as the original SVG animation is completely removed.
Karma Chameleon in light mode + no movement. (Large preview)
In dark mode + reduced motion, Karma Chameleon is in space with a stationary blue rocket in the background. In both environments, her colors and eyes are also stationary, as the original SVG animation is completely removed
Karma Chameleon in dark mode + no movement. ( both on desktop and mobile devices — meaning that more people can limit their exposure to unwanted movement on their screens. Unlike the media query @prefers-color-scheme which has a lot of competitors, there is currently no other motion reducing media query available.
Graph showing which browsers utilize the CSS at-rule: @media: prefers-reduced-motion media feature - IE and Opera mobile being the only major non-supporting browsers at this time; globally accepted 82.47%
Graph showing which browsers utilize the CSS at-rule: @media: prefers-reduced-motion media feature (

slots empire bonus codes
 Editorial (dm, yk, il)