6

I have a Gatsby project, where where I would like to use an svg as my main heading.

import Header from "../images/header.svg"

return (
  <h1>
      <Header/>
  </h1>
)

Thers is no text in the svg (the text is made purely using rects and paths), so what do I do in terms of accessibility and SEO optimization?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Boris Grunwald
  • 2,602
  • 3
  • 20
  • 36

1 Answers1

10

Two ways to address this, visually hidden text or by adding a <title> to your SVG.

Do not use aria-label as support is not great (you will see people recommending that for SVGs, aria-label does not tend to work well on static / non-interactive elements).

Visually Hidden text (screen reader only text)

Visually hidden text is not visible on the screen but will still be read by a screen reader.

Please use the CSS class below to visually hide text, it has better compatibility and is future proofed compared to most current "screen reader only" classes as explained in this answer I gave

.visually-hidden { 
    border: 0;
    padding: 0;
    margin: 0;
    position: absolute !important;
    height: 1px; 
    width: 1px;
    overflow: hidden;
    clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
    clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
    clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
    white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<h1>
  <span class="visually-hidden">Welcome To Our Site</span>
    <svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
        <path fill="#666" d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z">
        </path>
    </svg>
</h1>

important: notice how I add focusable="false" as well as aria-hidden="true" to the SVG, this is to fix a bug with Internet Explorer where SVGs are focusable and to hide the SVG from screen readers. I used a youtube icon to represent your text as that was the closest SVG I had to hand!

Add a <title> element to your SVG.

The <title> element is effectively the same as alt on a normal image. Using this gives the screen reader something to announce.

Obviously you would then remove the aria-hidden="true" from it so it can be read by a screen reader!

Update after comments to include best practices for <title> and or <desc>

Thanks to the comments I realised this answer was lacking some key information on how to correctly use a <title>.

In this answer I gave I referenced a series of tests by deque which show that the most reliable method for labelling an SVG for screen readers using WAI-ARIA was to use aria-labelledby and point that to the <title> (and <desc> if you have both).

So a rough idea of how to do this is as follows:

<h1>
    <svg aria-labelledby="welcome-title" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
        <title id="welcome-title">Welcome To Our Site</title>
        <path fill="#666" d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z">
         </path>
    </svg>
</h1>

Which is better?

Go for visually hidden text.

It works all the way back to IE6 which predates SVG!

It also works in a text only browser (one that does not understand CSS) as it will still be displayed. It is an edge case but still a win for visually hidden text!

GrahamTheDev
  • 22,724
  • 2
  • 32
  • 64
  • No problem, I have just updated it to tidy things up - just take note of the **important:** section for guidance as I only just added that. Glad it helped! – GrahamTheDev Dec 11 '20 at 19:39
  • desc should be roughly the equivalent of alt on a normal image. – Robert Longson Dec 11 '20 at 21:22
  • `alt` is for providing a brief description of an image, which is exactly what a `` is for in a SVG. `<desc>` is for providing more detailed information like a `<figcaption>`. [I answered about this here](https://stackoverflow.com/a/59563793/2702894), and here is a [reference on sitepoint that confirms](https://www.sitepoint.com/tips-accessible-svg/) and [a reference in the new code.](http://thenewcode.com/1026/Making-SVG-Accessible).</figcaption></desc> – GrahamTheDev Dec 12 '20 at 00:08
  • @RobertLongson [You have mentioned this before as a comment on this question](https://stackoverflow.com/questions/63208144/why-does-a-link-not-take-the-title-of-a-contained-svg-as-its-accessible-nam#comment111772807_63208144) but didn't respond to me then. Can you explain why `` is more appropriate than `` please as I do not want to be providing the wrong information to people in my answers, I can only go off what I have read and my interpretation of the W3C guidance. Would love to see an official source on something if you have that so I can quote it in my answers. – GrahamTheDev Dec 13 '20 at 12:56
  • These days [aria-describedby](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/desc) is actually recommended. – Robert Longson Dec 13 '20 at 13:27
  • Thanks for the response, but then we have the same issue (which one should you use) as [aria-labelledby](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title) is recommended with the `` attribute, which would still lead me to think `<title>` is more applicable as an alternative to `<alt>`. Also [deque did a great study on compatibility](https://www.deque.com/blog/creating-accessible-svgs/) and `title` and `description` linked via `aria-labelledby` and IDs was the most robust so [that is the recommended practice as I mentioned here](https://stackoverflow.com/a/59563793/2702894)</alt> – GrahamTheDev Dec 13 '20 at 14:00
  • I have updated my answer to include the important information I did not include when it comes to `` best practices, thanks @RobertLongson. I would still love to see why I would use `<desc>` and not `<title>` for the equivalent of an `alt` attribute if you have time to explain. – GrahamTheDev Dec 13 '20 at 14:07