Search code examples
htmlaccessibilitywai-aria

make text in ascii-art more accessible


on my website, I'm adding some text written in ascii art, and I'm not sure what is recommended in term of accessibility and semantic ?

the text is sometimes a single word, like "bio", and sometimes a group of words like a name "John Doe". For css reasons, I need to put them in a wrapper, and in case of several words I need to put each words in a different <pre> element :

<div>
  <pre>
••••  ••••• •••••
•   •   •   •   •
••••    •   •   •
•   •   •   •   •
••••  ••••• •••••
  </pre>
</div>

<div>
  <pre>
••••• ••••• •   • •   •
  •   •   • •   • ••  •
  •   •   • ••••• • • •
  •   •   • •   • •  ••
••    ••••• •   • •   •
  </pre>
  <pre>
••••  ••••• •••••
•   • •   • •
•   • •   • ••••
•   • •   • •
••••  ••••• •••••
  </pre>
</div>

I'm wondering :

  1. what is the right container element for this situation, in terms of semantics and accessibility ?
  2. if i need to add aria role and attributes to the container, which ones ?
  3. if I need to add aria role and attributes to the <pre> element, which ones ?

1. container

  1. <div> ?

    I could use the <div> generic container, I suppose it's always right, but is there a more appropriate one ?

  2. <figure> ?

    the mdn page for <pre>3 shows a case use with the <figure> element, is it appropriate in my situation ? In one hand, my two words "john" and "doe" are a single "figure" text, the division in two <pre> is just for css reasons, but in the other hand the aria documentation about the element <figure>5 state that it's not recommended to use this element if there is no <figcaption> inside

  3. <h1> ?

    since my text is used as a title, maybe my wraper should be a heading element ? the mdn page on headind1 says it can contains "phrasing content"2, which seems to includes things like images, but I don't see <pre> in the list, so I don't know if it's appropriate

2. container aria role and attribute

now depending of the container I decide to choose, I will have to add a role or not, trying to avoid specifying redundant roles12, but lets say I decide to go with <div>, what role should I give to this container ? I suppose it is the "heading" role8 ?

And I need to add a description, but how should I do that ? I can write the content as a description "John Doe", or should I better use two attributes, one to says "title in ascii art", and a second one with the content "John Doe" ? And finally, do i use aria for that or is there an html way of doing it ? Of course this last one certainly depends on the container element I use.

  1. with aria

    if i do it with aria, I suppose I can use "aria label"9 to write "John Doe", and if necessary (is it ?) I can use "aria-description"10 :

    <div role="heading" aria-label="JOHN DOE" aria-description="text written in ascii art">
    

    or maybe the aria-description is too much, since people using screen reader would not care about the fact that it is a title in ascii art, they just need to read the title ? :

    <div role="heading" aria-label="JOHN DOE">
    

    or maybe I should use "aria-label" only to specify the content and the fact that it is in ascii, like in the mdn page about <pre> in the example with a cow in ascii art3 ? :

    <div role="heading" aria-label="ASCII JOHN DOE">
    
  2. without aria

    or if I use a native html element with no need for aria, maybe that could be something like :

    <h1 title="JOHN DOE">
    

3. <pre> aria role and attribute

and finally, what should I do with the <pre> element : should I hide it to screen readers11 ?

<pre aria-hidden="true">

Or specify its content, as it's done in the mdn page about <pre> in the example with a cow in ascii art3 ?

<pre role="heading" aria-label="ASCII JOHN">

summarize

to summarize, my questions are :

  1. what container (<div>, <figure>, <h1>, other) ?
  2. what attributes for container (role, title, aria-label, aria-description, other) ?
  3. what attributes for <pre> (aria-hidden, role, title, aria-label, aria-description, other) ?

Without any counter-arguments, I think I would go for this :

<div role="header" aria-label="bio">
  <pre aria-hidden="true">
••••  ••••• •••••
•   •   •   •   •
••••    •   •   •
•   •   •   •   •
••••  ••••• •••••
  </pre>
</div>

<div role="header" aria-label="john doe">
  <pre aria-hidden="true">
••••• ••••• •   • •   •
  •   •   • •   • ••  •
  •   •   • ••••• • • •
  •   •   • •   • •  ••
••    ••••• •   • •   •
  </pre>
  <pre aria-hidden="true">
••••  ••••• •••••
•   • •   • •
•   • •   • ••••
•   • •   • •
••••  ••••• •••••
  </pre>
</div>

but I should add, this article13 advice against using aria-label on <div>


  1. mdn <h1> heading : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements
  2. mdn "phrasing content" : https://developer.mozilla.org/en-US/docs/Web/HTML/Content_categories#phrasing_content
  3. mdn <pre> : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre
  4. mdn <figure> : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure
  5. aria <figure> : https://www.w3.org/TR/html-aria/#el-figure
  6. mdn page on aria roles : https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles
  7. mdn on aria role="figure" : https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/figure_role
  8. mdn on aria role="heading" : https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/heading_role
  9. mdn on aria-label : https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label
  10. mdn on aria-description : https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-description
  11. mdn on aria-hidden : https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-hidden
  12. aria rule "avoid specifying redundant roles" : https://www.w3.org/TR/html-aria/#avoid-specifying-redundant-roles
  13. article on accessibility : https://html5accessibility.com/stuff/2020/11/07/not-so-short-note-on-aria-label-usage-big-table-edition/

Solution

  • How about the following?

    <h1>
      <div role="img" aria-label="Bio">
        <div aria-hidden="true" style="white-space: pre">
    ••••  ••••• •••••
    •   •   •   •   •
    ••••    •   •   •
    •   •   •   •   •
    ••••  ••••• •••••
        </div>
      </div>
      …
    </h1>

    You absolutely need to use an <h1> as a container for all users, including search engines, if it’s the page’s headline.

    role=img

    To make sense of ASCII Art, the visual impression is key. Hence, the corresponding role would be the img role.

    MDN mentions ASCII-Art in their article for the role as an example:

    Another example where this might be suitable is when using ASCII emoji combinations, like the legendary "Table flip":

    <div role="img" aria-label="That cat is so cute">
      <p>&#x1F408; &#x1F602;</p>
    </div>
    

    The ARIA in HTML standard also mentions an ASCII example which uses role=img.

    You should not hide it, about 20 % of screen reader users are sighted, so they might see the ASCII art, but badly. For them, it’s best to explain that it’s an image, and exactly what it says. In this case that’s simple, because dots are simply spelling out letters.

    However, screen readers provide access to the contents of the img, which is not helpful. So you might finally hide the contents themselves with aria-hidden, but not the img itself.

    Which text to use

    For users of voice control software, it’s also important that the represented word is the beginning of the accessible name, so that they can refer to the element by reading it aloud.

    A best practice is to have the text of the label [what the ASCII represents] at the start of the name [the aria-label].

    This way, you will respect WCAG criterion 2.5.3 Label in name

    Personally I think the aria-description is a great idea, even if support is lacking right now.