Chrome ignores aria-labelledby

I recently discovered that when a focusable element has some content in it and an assigned aria-labelledby attribute, a VoiceOver from MacOS doesn't read what's inside the label, but reads the focused component's content instead

Tried across different browsers: works as expected in Safari (11.1.1) but fails in Chrome (76.0.3809.100). Also tried changing roles of both elements.

<p id="header">This text should be read</p>

<div tabindex="0" aria-labelledby="header">
  <span>Click me</span>
  <p>This text should not be read</p>
</div>

https://jsfiddle.net/2d9jn4hs/

When you focus on the div with a VoiceOver on, I expect to hear This text should be read but hear Click me This text should not be read instead.

Any advice?

1 answer

  • answered 2019-08-24 07:01 Graham Ritchie

    Firstly what are you attempting to achieve?

    To my eye Chrome is behaving as expected and Safari is failing here.

    EDIT - actually after re-reading I cannot tell which one is behaving correctly due to how you worded it....however what you expect is wrong and you should indeed hear click me This text should not be read

    I would not expect the text within a focusable div to not be read....imagine how many sinister things you could do by showing one set of text to people without vision impairments and then a completely different set of information to blind people. (although this is entirely possible....)

    My advice.....rethink whatever it is you are trying to achieve and make the information the same for everyone.

    If you need to add ADDITIONAL information for screen readers try the 'visually hidden' class below which allows you to completely hide information from sighted users but still have it read to screen reader users.

    .visually-hidden { 
        position: absolute !important;
        height: 1px; 
        width: 1px;
        overflow: hidden;
        clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ <- if you REALLY must support ie7 and 6!
        clip: rect(1px, 1px, 1px, 1px);
        white-space: nowrap;
    }