Search code examples
htmlaccessibilitywai-ariavoiceoverscreen-readers

Voice Over Does Not Read Aria-label on iOS Safari but Screen Reader Reads on Chrome


I have a play icon that I want to be announced when it's focused. But interestingly, screen reader reads the aria-label. However, for iOS safari, using swiping gesture to the play icon does not announce the aria-label at all, and it only announce "link"

Here's the simplified HTML code:

  <div class="search-result">
       <i class="c-glyph" aria-label="there is video inside"></i>
  </div>

Does anyone know why?


Solution

  • First, I don't really think <i> is the correct choice here. That element is intended for idiomatic text such as technical jargon or special terminology. That's not the case here, and besides your <i> contains no text nodes. I gather it appears on screen as a CSS icon. <span> could handle that just as well, but it wont get you much closer to your intended (screen reader) results.

    Second, according to this useful reference about aria-label, <i> does not support aria-label because it maps to role="generic", which means naming is not allowed. This is true for almost all inline elements, including <span>, with <a> as the most obvious exception.

    So, if your simplified snippet is representative, then this is not a bug. The iOS behavior is correct according to the spec, and Chrome is doing the 'wrong' thing.

    If your play icon is an operable element (i.e. it does something when you 'click' it or 'touch' it) then you should use an explicitly operable element or ARIA role.

    The compellingly correct thing to use here would be <button>, but <a> (or role="link") might also be appropriate. If you decide to use an ARIA role, be sure to add tabindex="0" because you don't get tab focus 'for free' with ARIA.

    The markup might look like this:

    <a href="#" class="c-glyph" aria-label="there is video inside"></a>

    or

    <button class="c-glyph" aria-label="there is video inside"></button>

    or (using an ARIA role)

    <span role="link" tabindex="0" class="c-glyph" aria-label="there is video inside"></span>

    or (another ARIA role)

    <span role="button" tabindex="0" class="c-glyph" aria-label="there is video inside"></span>

    If you decide to use a <button> element you can style it however you like, but you probably want to begin by removing the default button styles provided by the user agent (browser), so in CSS you might have.

    button.c-glyph {
        background: none; /* css icon will override or replace this */
        color: inherit;
        border: none;
        padding: 0;
        font: inherit;
        cursor: pointer;
        outline: inherit;
    }
    

    And then you can specify whatever icon background is in the rule for your .c-glyph class.