Reputation: 14737
I use VoiceOver/Chrome on a iPad to test whether accessibility works on a page I am developing. I connect a Bluetooth keyboard to the iPad and click on the Tab key to go through elements on the page. The following code used on the page works with VoiceOver:
<div>
<div class="radio">
<label tabindex="0">
<input type="radio" name="abc" value="0" aria-labelledby="q1015678-2430294-button"> <span id="q1015678-2430294-button">Good</span>
</label>
</div>
<div class="radio">
<label tabindex="0">
<input type="radio" name="abc" value="1" aria-labelledby="q1015678-2430295-button"> <span id="q1015678-2430295-button">Bad</span>
</label>
</div>
</div>
However, when I use Screen Reader/Chrome on Windows, the above code pronounces "Good Good" before saying "Good, radio button". The same goes for the other "Bad" radio button when tabbing through the two choices.
What is the proper way of coding radio buttons that works with both VoiceOver and Screen Reader work?
Update
This is the HTML used in the test. VoiceOver fails to discover buttons coded in v2 and v3. It can identify and pronounce correctly "This the beginning", buttons in v1, and "This is the end".
I was able to tab through all buttons with the left/swipe gestures. The problem is to use the Tab key on a keyboard to tab through the buttons. The ios on the iPad is 15.4.1.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form>
<div tabindex="0" role="text">this is the beginning</div>
<div>-----------v1------------</div>
<div>
<div class="radio">
<label tabindex="0">
<input type="radio" name="abc" value="0" aria-labelledby="q1015678-2430294-button"> <span
id="q1015678-2430294-button">Good</span>
</label>
</div>
<div class="radio">
<label tabindex="0">
<input type="radio" name="abc" value="1" aria-labelledby="q1015678-2430295-button"> <span
id="q1015678-2430295-button">Bad</span>
</label>
</div>
</div>
<div>----------v2-------------</div>
<div>
<div class="radio">
<label for="q1015678-2430294-button2">
<input type="radio" name="ddd" value="0" id="q1015678-2430294-button2"> <span>Good 2</span>
</label>
</div>
<div class="radio">
<label for="q1015678-2430295-button2">
<input type="radio" name="ddd" value="1" id="q1015678-2430295-button2"> <span>Bad 2</span>
</label>
</div>
</div>
<div>-----------v3------------</div>
<div>
<label for="xyz1">radio button 1</label>
<input type="radio" id="xyz1" />
</div>
<div>
<label for="xyz2">radio button 2</label>
<input type="radio" id="xyz2" />
</div>
<div>-----------------------</div>
<div tabindex="0" role="text">this is the end</div>
</form>
</body>
</html>
If I put the following textbox in the form, the VoiceOver is able to pronounce it correctly with the tab key tabbing through the elements on the page.
<textarea name="ta">This is textarea</textarea>
Update 3
In my tests of v1 (the original code), the spacebar is able to activate a radio button on my ipad in both Safari and Chrome.
Upvotes: 4
Views: 2804
Reputation: 14882
As explained in this answer, activating the "full keyboard access" option make the radio buttons reachable with tab as they normally should. My first answer giving advice on the code stays valid.
The good news is that what we have observed isn't a bug. Apple made it working like this intentionally.
The bad news is that VoiceOver and full keyboard access aren't playing well together.
For example, when full keyboard access is turned on, I can no longer enable/disable quick navigation, and I have big troubles using the rotor. Several other important VoiceOver functions seem to be affected, too. As a blind and VoiceOver user, I really can't keep full keyboard access enabled.
From there, one can deduce that, as a screen reader users, you aren't supposed to use tab to navigate. You should exclusively be using screen reader specific functions. Here, VO gestures.
It also shows that, in fact, your test is incorrectly designed:
If, on a PC, you can test both at the same time, it looks like it's not on iPhone and iPad, because Apple seem to have decided to completely separate the two kinds of users. It would be interesting to know why, and where the most goes the macintosh.
Upvotes: 1
Reputation: 14882
At a first glance, two things look strange in your code:
For the first point, the tabindex=0 on the label make that label focusable. However, the label isn't supposed to be focusable. Only the radio button should be, and it is by default without specifying tabindex. This is precisely why you first reach the label by itself, and since you first reach the label by itself, you can't do anything with it.
Solution: remove tabindex=0 from the label
For the second point, it might work, but it's still quite an odd construction. The aria-labelledby has to be used when you need to reference a labelling element different than the normal label.
<label>
references the <input>
element in its for
attribute, you don't need an additional aria-labelledby.<label>
as the <input>
, you don't need aria-labelledby either.<label>
be the actual accessible label, you'd better switch to another more conventional construction where the <input>
isn't inside the <label>
. Then there will be less confusion when using aria-labelledby, if you want still to have a different accessible label than what's inside the <label>
.I hope it's clear enough. My advice: switch to a simpler construction like this:
<div>
<label for="xyz">Label of the radio button</label>
<span>Some additional text not present in accessible label, if you want</span>
<input type="radio" id="xyz" />
<span>Some additional text not present in accessible label, if you want</span>
</div>
Upvotes: 3