Accessible SVG: A Practical How To

I Heart SVG graphic I SVG

Three years ago I fell in love. With SVG. It was a love affair that was meant to be. I adore vector graphics, accessibility, and code — and SVG is all of that and more.

But this affair was cursed by two things: my lack of time and older versions of both Internet Explorer (IE) and Android. (A small aside: I take an odd delight that Microsoft (IE) is not the only “bad guy.” Google and cellular companies are as well.)

In any event, one of those two (lack of time) is now solved. Retirement, while far from a state of being retired, is nevertheless a wonderful thing.

And then, oh joy, I happened upon LĂ©onie Watson’s SitePoint article on Tips for Creating Accessible SVG. My old flame reignited.

Inspired, I began mucking around — combining her tips with the ugly reality that SVG still chokes in IE 8, Android 2.3, and earlier versions of both. Alas, it’s still risky to ignore these elders if you want to build a truly accessible site. To the rescue: Chris Coyier’s classic SVG Fallbacks article.

Add to the mix that I usually create SVG using Adobe Illustrator CS6 — and it creates ugly, but seemingly effective, code. If that’s not bad enough, WordPress is my CMS-of-choice, and it eats SVG for lunch. So two other things I’ve been playing with are how best to clean up Illustrator’s nasty code and then how to retain SVG code in a WordPress post.

Here’s the optimal workflow I’ve come up with thus far.

By the way, I’m assuming your code is HTML5 and that you’re familiar with Modernizr.

Step 1: Clean Up Illustrator SVG

I hear Inskape is the SVG go-to tool, but I’ve never tried it. (I will soon. Looks fun.) Meanwhile, for those like me habituated to Adobe…. I start by creating a graphic in Illustrator. If you’re loading a graphic that’s already been sized, you can skip to step 2. Here are my steps:

  1. File > New…. Before you click the OK button, be sure the “Units” are “Pixels” and you’ve set the height and width you’d like. If you don’t do this Illustrator will probably make a large file with crazy 3 decimal places dimensions like width=”188.032px” and height=”193.316px.” Then create your image. (Optional. Me — I like to save it first as a native Illustrator file (.ai) before going on to….)
  2. File > Save As… > Format: SVG (not SVG Compressed) > Save.
  3. In the box that pops up after you hit Save, choose:
    • SVG Profiles: SVG 1.1;
    • Type: SVG (not Adobe CEF);
    • Subsetting: None;
    • Image location: Embed;
    • OK.
  4. Close Illustrator. Open your new SVG file in your code editor of choice.
  5. Delete the first three lines of code: an XML line, a comment line and a DOCTYPE line.
  6. The next line (which starts the SVG) is kind of a mess. For this example it originally read:
    <svg version=”1.1″ id=”Layer_1″ xmlns=”http://www.w3.org/2000/svg” xmlns:xlink=”http://www.w3.org/1999/xlink” x=”0px” y=”0px” width=”150px” height=”150px” viewBox=”0 0 188.032 193.316″ enable-background=”new 0 0 188.032 193.316″ xml:space=”preserve”>

    • Delete everything except the version, height and width.
    • Add an “aria-labelledby” attribute that will correspond with the title id you add in Step 2, #1 below.
    • If you include the optional description (Step 2, #2 below) expand the “aria-labelledby” attribute to include the desc id.
    • Add the ARIA role attribute of image. This may sound daunting, but it’s actually really simple. You just add ‘role=”img”‘ to the initial SVG line of code.
    • Thus far in this example, the code looks like this:
      <svg version="1.1" width="150px" height="150px" aria-labelledby="mysvgtitle mysvgdesc" role="img">

Step 2: Add Text Elements

The key to making SVG accessible is how you add various chunks of text — particularly how you use the title element. (An aside: an SVG title is an HTML "element" – not an "attribute". And the "tag" is the code in brackets, e.g. <title> is a start tag.)

  1. A title. This is a must if the graphic is not purely decorative. It’s the equivalent of the image alt attribute. To do this, on the second line (just below the initial <svg> tag), add a title using the <title> element, e.g. <title id=”mysvgtitle”>My stars</title>.
  2. A description. Optional. If you need to add more information than what’s in the title, add the <desc> element on line 3, e.g. <desc id="mysvgdesc">Demonstration graphic….</desc>. Be warned, however, that those naughty older browsers (Android 2.3, IE 8, etc.) will show the description while they don’t show the title. More on this in Step 3 below.
  3. Text. Optional. If your image has text, you can include it as actual text in the SVG code. (It’s a beautiful thing.) To do this, use the SVG <text> element — being sure to (a) position it along the x/y axes and (b) give it a "text-anchor" attribute of start, middle or end (the equivalent of align left, center or right) — e..g. <text x="75" y="75" text-anchor="middle">My stars!</text>.
  4. Here’s what the example code looks like thus far (with important code in bold):
    <svg version="1.1" width="150px" height="150px" aria-labelledby="mysvgtitle mysvgdesc" role="img">
    <title id="mysvgtitle">My stars</title>
    <desc id="mysvgdesc">Demonstration graphic showing how to create accessible SVG.</desc>

    <polygon fill="#FBB040" points="74.025,2.132 95.818,46.291 144.55,53.372 109.288,87.744 117.612,136.278 74.025,113.364 30.438,136.278 38.763,87.744 3.5,53.372 52.232,46.291 "/>
    <polygon fill="#FFDE17" points="38.481,12.324 80.363,38.224 125.442,18.406 113.753,66.241 146.532,102.989 97.426,106.654 72.604,149.184 53.945,103.613 5.826,93.15 43.4,61.322 "/>
    <text x="75" y="75" text-anchor="middle">My stars!</text>
    </svg>

Step 3: Accommodate IE and Android

Screenshot of substitute graphic in Android 2.3. Note that the description and text are below.

Screenshot of substitute graphic in Android 2.3. Note that the description and text are below.

  1. Be sure to include SVG in your build of Modernizr; this creates a “no-svg” class for problem browsers;
  2. Create a png or gif version of your graphic;
  3. Add a little CSS like Chris Coyier’s (substituting the height and width of the png or gif graphic you just created): .my-svg-alternate {
    display: none;
    }
    .no-svg .my-svg-alternate {
    display: block;
    width: 150px;
    height: 150px;
    background-image: url(my-stars.png);
    }
  4. Add the following line of code before the SVG. The reason to have it before is if there’s a description and/or text in the SVG, they will show after the image. <div class="my-svg-alternate"></div>

Extra Credit: Add SVG to a WordPress Post

If you wish to use SVG in a WordPress post (such as I’m doing here), you’ll have to use the WordPress "Text" tab. Here’s the trick: you must make your SVG all one line. If you don’t, WordPress will add HTML breaks and paragraphs and munge the code so it doesn’t work.

In addition, thereafter you must remain in the "Text" (HTML code editor) tab. If you switch to the "Visual" tab, all the code will be deleted and only the title text will remain. Later, if you accidentally open it in the "Visual" tab your SVG will appear to have been eaten. Whatever you do, don’t save it at this point. Switch to the "Text" tab, go to some other admin page (e.g. the dashboard) and then return to your post.

In other words, using SVG in WordPress posts is not for the faint-of-heart.

The Result

The result of this work? An elegantly coded accessible graphic. I realize this is a lot of fiddling, but then again in my experience most good Web graphics take a lot of fiddling to get just right. And SVG is the future. So why not exercise your geek graphic chops?

My starsDemonstration graphic showing how to create accessible SVG.My stars!