Web Accessibility of Checkboxes, Radio Buttons: the Fieldset
When I talk with other developers who don’t have a strong background in web accessibility, they are often taken aback when I tell them that radio buttons and checkboxes should be wrapped in a
The Problem with the Usual Approach
Here’s a simple two-option set of radio buttons:
Although I’ve seen some absolute coding atrocities on even large e-commerce sites, most polished developers produce something like this:
<h3>Gender</h3> <input type="radio" name="gender" id="gender_f" checked="checked" /> <label for="gender_f">female</labe> <label for="gender_m">male</label>
This is not bad for what it is, but it’s not quite right, either. But most importantly, it’s not really accessible.
The problem is that the “question” (gender) is not programmatically associated with the possible answers (female or male). This can be a problem for screen readers. Most screen readers operating in their default mode, like JAWS’s PC Cursor mode, will read the word “gender” in the example above and “guess” that it’s related to the radio buttons that follow it.
But when the screen reader goes into forms mode, allowing the user to skip from form field to form field using the tab key, it doesn’t always work, leaving the user guessing what the question is that the particular radio button is answering. In this simple example, it’s probably easy enough for the user to guess if the screen reader speaks “female” without also speaking “gender”, but if this were a mortgage application, for instance, it could leave the user guessing, “Is it asking me for the applicant’s gender or the co-applicant’s gender?”
<fieldset> to the Rescue!
The solution is to wrap everything — the question and all the answers — in a
<fieldset> tag. The question itself gets wrapped in a
<legend> tag so the code looks something like this:
<fieldset> <legend>Gender</legend> <input type="radio" name="gender" id="gender_f" checked="checked" /> <label for="gender_f">female</label> <label for="gender_m">male</label></fieldset>
It produces something that looks like this:
If the default display of the fieldset doesn’t fit with the design of the rest of the page — and often it won’t —, it can be styled using CSS. The Man in Blue site has some examples on styling the
Wait, There’s One More Thing to Consider
There’s one more thing, though. There is only limited styling support for the
<legend> tag itself. Thanks to my colleague, Dan Herbert, for forwarding me a post from Marc Pacheco about just how poor browser support is for styling this tag.
Not surprisingly, the second part of my conversation with my developer colleagues is about how to style the
<legend>. Usually the aim is to make it not look like a legend. The simple answer is to wrap the content of the
<legend> tag in another tag. The
<span> tag is the most common choice. Those of us who fret about semantic code rightly squirm at this solution, but as far as accommodations go, this one is a pretty minor compromise. Tyssen Design’s article, Legends of Style is a few years old but shows some of the nitty-gritty style coding.
Radio buttons and checkboxes work largely the same way and should both almost always be wrapped in a fieldset. “Almost”? There is one exception for checkboxes for which a fieldset should not be used. This is when a single checkbox is used to answer a true/false yes/no question.
The code for this looks like this:
In this case, having a
<fieldset> tag would be redundant and would actually harm accessibility.
Even front-end developers who are strict adherents to Web Standards might not be aware of the correct web accessibility approach to checkboxes and radio buttons. These form elements should be wrapped in a
<fieldset> tag with the question they answer held in the
<legend> tag. Because of the limited browser support for styling the
<legend> tag, its contents often have to be wrapped in another tag, like
<span>. The one time when a fieldset should not be used is when a single checkbox is used to answer a yes/no question.