htmlaccessibilitywai-ariawai

Accessibility of a text with inline <svg>


I have the following code:

<h2>
    Deadpool
    <svg width="53" height="64" class="inline" aria-label="and">
        <use href="#oleo-ampersand"></use>
    </svg>
    Wolverine:<br>
    A StackOverflow Example
</h2>

The ampersand is stylized as follows:

enter image description here

Now, I want screen readers to narrate it as a regular phrase (i.e.“Deadpool and Wolverine”). Adding aria-label="and" to the <svg> seems to be ignored. Is there a way to achieve this? Maybe, I should make the whole block aria-hidden and add a visually hidden element instead?

Also, it would be cool to make the block being copied the same way on Ctrl+C, but I guess it's not possible without a JS intercepting.


Solution

  • You may also apply the .sr-only class only to a hidden <span> with the text content "and".

    If your SVG doesn't contain any text elements you may even omit the aria-hidden attribute.

    To avoid browser inconsistencies when copying the text we can:

    You as well use a span with a subset version of the desired font applied (1. example). In this case you would need to apply aria-hidden="true" and make it unselectable via user-select:none

    body {
      font-family: sans-serif;
    }
    
    /** subset version of Oleo - only including ampersans **/
    @font-face {
      font-family: "Oleo Script Swash Caps";
      font-style: normal;
      font-weight: 700;
      font-display: swap;
      src: url("data:font/woff2;base64,d09GMgABAAAAAAMMAA8AAAAABfAAAAK5AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbDBwYBmAAPBEICoFggV0LCAABNgIkAwwEIAWEfAcgDAcb4wTIBB74POv9JAM4Y67Agdzuul3iavAk5uevyUfH3wZyAYCR78cyKJoaK2w+kQLK4JlOZAPjqcYWu4QOsXcpavUIwBoHhE2kg/aBWBrGDVylURSkVhRhTm6WJQ/pECYgGaSRSvucZGI8CcIiLJE4OpkN5elMSW1ZOSoqIfKn/1OtivxJ1KtVFBEHpY+GqKS242RwViIUKYRxplojyyohmkaqJqM91x5lNzqR0TTsmqgfmOkF+oJNJDxK/f6z3M7MPHuxzt3ScEt33Xg38JzhgOfSjW6rjXfv3jXe1t0y9L91y9LQ+87wLfoud0ecuSP0d4230V0zXNG32XVMdzw5Vb/B0POy8cFKves6dIs3bonwTzPtPKrf9N9ZfUZtbOi6R+eaP88zrFto15gRoYM7JUzs3KkoVGQsXVHU5WIvP59OSml8p1F1yriu/Vr0aRy+uqRH2/Da/kVD2tzo3//b3sjZ1ilxW1P6fA++E/zps6/VIwBo6TXB5NerCidPsGv7zdxKfofcpTPnI04HtdT/U5UA+RMC897Hore1Pm9TOmqpmqkS0GNW4pLFV5xzkpYu0OlHXGbsKJvjYcwNT0c2bk7W6PgUC03dER1vgiBKOAsS5sJakBnJLkEhhSbBBE8yBFPiSAJbvAM5VFBBCa2JJZZy0ikjlxIqBMVQ/ssCYiimjGxiGUB3+jKAAjIpZgipyOZqUiknhy6kUoJN0XSmmAIyGG5IWTGviilCJZ4Y4ogjAdOqTKrqUZVXv4shFFNLBZVUUEsJmbRGDbRMrQnEEU/C68gKgS5IlFBLkOyBXKwSRjrhRZKobD2bazDaYHy6glTSqaAj5QGJASokZl4ZDYh1JBssdZIMkoRXF6smF1pDY2VkQpuAYhWZZIBlVQpFSgob4gntMgtd12uh7SaBpHqf0KZuU2YD")
        format("woff2");
    }
    
    .ampersand {
      font-family: "Oleo Script Swash Caps";
      font-weight: 700;
    }
    
    
    /* SVG ampersand */
    .svgText {
      height: 1em;
      transform: scale(1.5) translateY(0.1em);
    }
    
    
    .non-select{
        user-select:none
    }
    
    /* hide for not impaired readers */
    .sr-only {
      clip-path: inset(50%);
      height: 1px;
      overflow: hidden;
      position: absolute;
      white-space: nowrap;
      width: 1px;
      outline:1px solid #ccc
    }
    
    textarea {
      display: block;
      width: 100%;
      min-height: 10em;
    }
    
    h2{
      white-space: nowrap;
    }
    <h2>
        Deadpool <span aria-hidden="true" class="non-select  ampersand">&</span><span class="sr-only">and</span>
        Wolverine
    </h2>
    
    <h2>
    Deadpool <svg class="svgText" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 75 138.3"  aria-hidden="true"><path class="glyph" d="M36.2 57.3 L36.3 57.3 Q36.6 58.4 36.6 60.1 Q36.6 61.7 35.9 63.6 L35.9 63.6 L35.3 63.6 Q28.7 63.6 24.2 67.5 Q19.7 71.4 19.7 78.2 Q19.7 84.9 22.9 87.9 Q26.1 90.8 31.2 90.8 Q36.3 90.8 40.1 86.3 Q43.9 81.8 45 75.8 L45 75.8 Q39.4 78.7 36 78.7 Q32.6 78.7 30.4 77.6 Q28.2 76.4 27.3 74.7 L27.3 74.7 Q27.5 74 28.6 72.6 Q29.8 71.2 30.8 71.1 L30.8 71.1 Q32.6 72.2 34.6 72.2 Q36.6 72.2 40.1 70.2 Q43.6 68.2 47.1 65.8 Q50.5 63.5 54.9 61.5 Q59.3 59.5 63.4 59.5 Q67.5 59.5 70.8 62.1 Q74.1 64.6 74.1 69.4 Q74.1 74.2 70.8 77.5 Q67.4 80.8 61.9 80.8 Q56.4 80.8 51.3 76.8 L51.3 76.8 Q51.1 86.9 43.5 94.7 Q35.9 102.4 24.9 102.4 L24.9 102.4 Q18.2 102.4 12.1 99.6 L12.1 99.6 Q4.7 96.4 1.7 89.8 L1.7 89.8 Q0 86.1 0 80.5 Q0 74.8 3.6 69.8 L3.6 69.8 Q10.2 60.8 22.5 60.3 L22.5 60.3 Q17.1 58.9 13.7 55 Q10.2 51.1 10.2 45.6 L10.2 45.6 Q10.2 38.1 16.5 33.8 Q22.8 29.4 31.1 29.4 Q39.3 29.4 45 33 Q50.6 36.6 50.6 42.6 L50.6 42.6 Q50.6 46.7 47.8 49.6 Q45 52.5 41.1 52.5 Q37.2 52.5 34.5 50.2 Q31.7 47.8 31.7 43.7 Q31.7 39.5 35.3 36.7 L35.3 36.7 Q30.7 37 28.9 40.2 Q27 43.3 27 47.2 Q27 51.1 29.4 53.8 Q31.8 56.5 36.2 57.3 L36.2 57.3 ZM66.2 71.5 L66.2 71.5 Q66.2 70.3 65.2 69.2 Q64.2 68 61.8 68 Q59.4 68 53.5 71.2 L53.5 71.2 Q58.7 75.1 62.5 75.1 Q66.2 75.1 66.2 71.5 ZM40.6 45.7 Q41.5 45.7 42.2 44.6 Q42.9 43.4 42.9 41.6 Q42.9 39.7 41.4 38.4 L41.4 38.4 Q38.2 40.3 38.2 43.3 L38.2 43.3 Q38.2 44.4 38.9 45.1 Q39.6 45.7 40.6 45.7 Z " /></svg><span class="sr-only">and</span> Wolverine
    </h2>
    
    <h3>Paste text</h3>
    <textarea></textarea>

    The commonly used sr-only rules ensure the text is still readable by screen-readers and selectable - although invisible for sighted users. The main trick of this technique is to make the element invisible by multiple properties without applying disply:none or visibility:hidden as both properties would remove the content from the accessibility-tree.

    See also "The A11Y Project: Hide content"

    SVG to font conversion

    If your inline SVG graphic is not available as a font - you may also use a SVG-to-font-generator like icomoon or fontello to convert your assets to an icon font.

    Subsetting

    If your font service doesn't support subsetting you may also convert it with a service like transfonter. It also has an option to generate base64 encoded dataURLs of the font resource.