1

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?

Konstantin
  • 55
  • 10

2 Answers2

5

Take a look at "Practical Support: aria-label, aria-labelledby and aria-describedby", in particular, the third last bullet:

Don't use aria-label or aria-labelledby on a span or div unless its given a role. When aria-label or aria-labelledby are on interactive roles (such as a link or button) or an img role, they override the contents of the div or span. Other roles besides Landmarks (discussed above) are ignored.

The emphasized text, "they [aria-labelled] override the contents of the div or span", sounds like the behavior you're looking for.

So you need to specify a role for your "clickable" thing, preferably a role that is an interactive role such as a Widget Role

slugolicious
  • 15,824
  • 2
  • 29
  • 43
  • Yay! Worked like charm. I saw that paragraph and tried assigning roles but apparently wrong ones. A generic `role="group"` did the trick. – Konstantin Aug 27 '19 at 07:39
  • Which is actually a bit weird, since (if I get it right) it already has an implicit `role='group'` assigned. – Konstantin Aug 27 '19 at 07:48
  • The example you posted had p, div, and span elements. None of those have an implicit role. Which element do you think has an implicit group role? – slugolicious Aug 29 '19 at 13:46
  • The problem only appears on MAC, windows OS is fine. And by adding the role attribute I managed to fix voice-over. Well done for this solution. – Sergiu Mare Jul 22 '21 at 13:13
  • 1
    @SergiuMare Yeah, it's unfortunate that OS and screen reader combinations vary so much in how they behave, but it's a pretty well documented that aria-label on non-semantic elements is generally ignored until you provide a role. – slugolicious Jul 22 '21 at 21:18
2

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;
}
GrahamTheDev
  • 22,724
  • 2
  • 32
  • 64
  • Okay, so my use case is: I have a modal with all kinds of visual information *and a header*. It opens on button click and when it does, I focus on the modal and I want a screenreader to not read everything what's inside the modal, but only the header. The thing is, when I use `aria-label` it does exactly what I want. But when I use `aria-labelledby` (which to me seems like pretty much the same thing) it does something different. – Konstantin Aug 24 '19 at 07:20
  • Why don't you want it to read the modal? I had a similar conversation with someone the other day and he wanted the screen reader to stop reading after a certain line. This is the opposite of how a screen reader should behave as you want to 'read ahead' so you know what to expect. Is this what you are trying to achieve or am I misunderstanding? – GrahamTheDev Aug 24 '19 at 07:25
  • https://stackoverflow.com/questions/57302603/nvda-reads-all-modal-content-after-reading-the-focused-element-in-modal-dialog/57313413#57313413 <- see if this helps. – GrahamTheDev Aug 24 '19 at 07:26
  • Yeah, that's pretty much what I want. It has lots of stuff going on and in order for it to make sense for a screenreader it'd take enormous effort (or just throw a bunch of `aria-hiddens` around which would do the trick, but I'm saving it as a last resort), while visually information is well organized and makes sense from the first view. My main concern for now is why `aria-label` and `aria-labelledby` don't do the same thing? `aria-label` seems to be _stronger_ than `aria-labelledby`? – Konstantin Aug 24 '19 at 07:32
  • 1
    That is actually by design - `aria-label` is a method designed for labels for inputs etc. so is designed to be assertive. `aria-labelledby` is supplementary (additional) information designed for things like charts, complex images etc. where you want to just add some extra info. – GrahamTheDev Aug 24 '19 at 07:41
  • Also yet again don't try and dictate how the screen reader works. If there is a lot of information a person using a screen reader wants the same experience as a sighted user. Just make sure your HTML is semantically correct and you will be fine most of the time. – GrahamTheDev Aug 24 '19 at 07:43
  • 2
    The fact that your focusable div has no role may influence the result. If it is a button (what it probably assume here), reading only the text inside the focused element and nothing else is a common behavior, since buttons have no label additionally to their text. In any case, I recommand to set a role for any focusable div or span. – QuentinC Aug 25 '19 at 11:17
  • Thanks for the comment! Yes, role button worked but the problem is that the whole thing is not a button, so whole experience was quite confusing. Anyway, a generic `role="group"` did the trick – Konstantin Aug 27 '19 at 07:46
  • Graham, you're mistaken about the difference between `aria-label` and `aria-labelledby`. They both share the same purpose: to define the accessible name of the element. For the "supplementary informatiion" scenarios you describe, there is `aria-describedby`. ARIA 1.1 also intoduced `aria-details` but it is poorly supported at present. – andrewmacpherson Sep 08 '19 at 08:54