An alternate solution would use a combination of label and aria-describedby. This is supported with NVDA and JAWS on Windows and Safari + VoiceOver on Mac.
Suggested by Jared Smith, this role recreates the radio button semantics. The radio button container has role="radiogroup"
and aria-labelledby="gender"
. The individual inputs do not need to reference the gender.
<div class="wrapper"> <div class="label required" id="gender2">Gender:</div> <div class="field" role="radiogroup" aria-labelledby="gender2"> <span fieldid="gender" class="choice" id="id10"> <table> <tbody> <tr> <td> <input type="radio" id="role1" value="2" name="foo" > <label for="role1">Male</label> </td> <td> <input type="radio" id="role2" value="1" name="foo" > <label for="role2">Female</label> </td> </tr> </tbody> </table> </span> </div> </div>
The original code used a label for the header and table based markup for the inputs and labels
<div id="id10_row" class="wrapper"> <div class="label required"> <label for="id10" class="label required">Gender:</label> </div> <div class="field"> <span fieldid="gender" class="choice" > <table> <tbody> <tr> <td> <input type="radio" id="id10-2" value="2" name="editPersonalInfo:border:editForm:inputs:4:input:input"><label for="id10-2">Male</label> </td> <td> <input type="radio" id="id10-1" value="1" name="editPersonalInfo:border:editForm:inputs:4:input:input"><label for="id10-1">Female</label> </td> </tr> </tbody> </table> </span> </div> </div>
The new markup uses a fieldset with legend. There is no need for table based markup to keep them inline. Just a few lines of CSS.
.inline {border:none; width:600px;} .inline * {display:inline-block; } .inline legend {border:none; text-align:right; width:200px; float:left; } <fieldset class="inline"> <legend class="required">Gender</legend> <input type="radio" id="id12-2" value="2" name="editPersonalInfo:border:editForm:inputs:5:input:input"> <label for="id12-2">Male</label> <input type="radio" id="id12-2" value="1" name="editPersonalInfo:border:editForm:inputs:5:input:input"> <label for="id12-1">Female</label> </fieldset>
This example removes the label wrapper for "Gender" and uses aria-describedby to connect the radio buttons to this heading.
<div id="id10_row" class="wrapper"> <div class="label required" id="gender">Gender:</div> <div class="field"> <span fieldid="gender" class="choice" id="id10"> <table> <tbody> <tr> <td> <input type="radio" id="id11-2" value="2" name="editPersonalInfo:border:editForm:inputs:4:input:input" aria-describedby="gender"><label for="id11-2">Male</label> </td> <td> <input type="radio" id="id11-1" value="1" name="editPersonalInfo:border:editForm:inputs:4:input:input" aria-describedby="gender"><label for="id11-1">Female</label> </td> </tr> </tbody> </table> </span> </div> </div>