Skip to content

Web Accessibility of Checkboxes, Radio Buttons: the Fieldset

by on November 23, 2010
Code review

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 <fieldset> tag.

The Problem with the Usual Approach

Here’s a simple two-option set of radio buttons:

Radio buttons "female" and "male" answering the question "Gender"

Although I’ve seen some absolute coding atrocities on even large e-commerce sites, most polished developers produce something like this:

<input type="radio" name="gender" id="gender_f" checked="checked" />
<label for="gender_f">female</label>
<input type="radio" name="gender" id="gender_m" /> 
<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:


  <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:

Radio buttons "female" and "male" with fieldset box around them. The word "Gender" is inset in the boxIf 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 <fieldset> tag.

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.

Except for…

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.

A checkbox followed by the words "I accept the terms of use"The code for this looks like this:

<input type="checkbox" name="acceptterms" id="acceptterms" value="accepted" />
<label for="acceptterms">I accept the terms of use</label>

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.

Update: This post originally was missing the correct label code for the gender example above. The code has been corrected.

  1. Thanks for writing this up!

    Your example doesn’t have radio buttons for the “male” selection. Here it is included:





Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: