|
<!doctype html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<title>Accessible radio buttons using aria-labelledby</title> |
|
</head> |
|
<body> |
|
<main role="main"> |
|
<h1>Accessible radio buttons using aria-labelledby</h1> |
|
|
|
<p>The problem we have with radio buttons is we use the <code>label</code> element to mark up possible responses instead of marking up the question, which is the opposite of what we do for text-y form elements. This is a problem for screen readers, which associate the value of the <code>for</code> attribute of a <code>label</code> element, which will be the question in text-y elements, with the value of the <code>id</code> of the form element, which will be input field for text-y elements. When in forms mode, JAWS will jump to form elements on a page, ignoring other content (e.g. headings and other text). This means your question is going to be ignored, forcing the user to jump around the page to try to find the context for whatever the radio buttons are referencing. The solution to this problem comes with the <code>aria-labelledby</code> attribute, which allows us to link multiple elements together by referencing their <code>id</code> attributes in whatever order makes sense for comprehension. Using <code>aria-labelledby</code>, we can mark up the question and answer responses so a screen-reader user can hear what they need to successfully answer the question.</p> |
|
|
|
<section id="without-aria"> |
|
<h1>Inaccessible example</h1> |
|
|
|
<form action="#" id="form1"> |
|
<h2>What color is your inaccessible car?</h2> |
|
<input type="radio" name="color1" id="color1"><label for="color1">Red</label> |
|
<input type="radio" name="color1" id="color2"><label for="color2">Green</label> |
|
<input type="radio" name="color1" id="color3"><label for="color3">Blue</label> |
|
</form> |
|
|
|
<p>Tested in JAWS using Internet Explorer, the user hears: <q>Red radio button not checked; green radio button not checked; blue radio button not checked</q>. Boo.</p> |
|
|
|
</section> |
|
|
|
<section id="with-aria"> |
|
<h1>Accessible example</h1> |
|
<form action="#" id="form2"> |
|
<h2 id="carcolor">What color is your accessible car?</h2> |
|
<input type="radio" name="2" id="color4" aria-labelledby="carcolor color-choice-1"><label id="color-choice-1" for="color4">Cyan</label> |
|
<input type="radio" name="2" id="color5" aria-labelledby="color-choice-2"><label id="color-choice-2" for="color5">Magenta</label> |
|
<input type="radio" name="2" id="color6" aria-labelledby="color-choice-3"><label id="color-choice-3" for="color6">Yellow</label> |
|
<input type="radio" name="2" id="color7" aria-labelledby="color-choice-4"><label id="color-choice-4" for="color7">Black</label> |
|
</form> |
|
|
|
<p>Tested in JAWS using Internet Explorer, the user hears: <q>What color is your accessible car, cyan radio button not checked; magenta radio button not checked; yellow radio button not checked; black radio button not checked</q>. Yay! If you want to repeat the question on every answer choice then it's simply a matter of adding in the <code>id</code> attribute of the question to the <code>input</code> element.</p> |
|
|
|
<p>It’s important to note that the order of values in the <code>aria-labelledby</code> attribute matters. If you reversed them in the example above, the user would hear <q>Cyan, what color is your accessible car?</q>, etc. You should ensure you specify the order of the attributes so follow the logical order of question followed by answer(s).</p> |
|
|
|
</section> |
|
|
|
</main> |
|
</body> |
|
</html> |