Use the label element to make your HTML forms accessible

There are plenty of articles and tutorials that describe how to create accessible HTML forms out there. Despite that it is common to come across forms that do not use a single label element and forms that use label elements but do so incorrectly.

Forms that do not use label elements properly will cause accessibility problems for some users, which is bad. Apparently then, there is room for more writing on this subject, so here is a brief explanation of the label element, how it should be used, what problems can be caused by not using it, and what the benefits of using it are.

The label element associates information with a form control, letting the user know what purpose the form control has. Each label element can only be associated with a single form control, while a form control may have several labels associated with it. This could be very useful for displaying hints and error messages since it would let you separate those messages in the markup for much easier positioning and styling. Unfortunately my limited screen reader testing (JAWS 8.0 and VoiceOver) of multiple labels suggests that screen readers ignore them.

All visible form controls except buttons should have an associated label element (buttons are self-labelling). The label element can be associated with its form control either implicitly or explicitly.

An implicit association is created by putting the form control inside the label element, while an explicit association is created by giving the label element a for attribute with the same value as the form control's id attribute.

I always use and recommend explicit association since it feels less awkward and more exact, and has better browser compatibility (IE 6 only makes explicitly associated labels clickable). I feel that explicitly associated labels also allow for easier styling and scripting.

I started this article by saying that the lack of label elements will cause accessibility problems. I wasn't being specific, so you may be wondering exactly what those problems are. The main issues are:

  • Screen readers will have to guess which text to announce to the user by looking at things like the surrounding text and the form control's title and name attributes. Sometimes they get it right, other times not. But the point is they shouldn't have to guess.
  • People that can use a mouse but lack or have reduced fine motor control will have problems targeting checkboxes and radio buttons (they are really small). When checkboxes and radio buttons have properly associated labels, the label text will also be clickable, thus making the target area much larger and easier to hit. This obviously has usability benefits for all users.

Here is an example of an explicitly associated label element:

  1. <div class="text">
  2. <label for="firstname">Enter your first name:</label>
  3. <input type="text" name="firstname" id="firstname">
  4. </div>

The div element is what I normally use to group each label with its form control (for grouping several label + input combos I use fieldset elements where appropriate). It makes the form reasonably readable when CSS is off, provides a good hook for CSS, and makes sure my form elements do not contain any inline level elements (which is not allowed in strict doctypes).

If you want to display the label text above the input field instead of on the same line, it's easy to use CSS to set the label element's display property to block:

  1. .text label {
  2. display:block;
  3. }

Some like to use a br element instead, which also makes sure that there is a line break after the label when CSS is not supported. I go with the CSS approach, but use whatever works best in your particular siuation.

Some tutorials suggest using CSS to change the mouse cursor into a pointer when it is placed over a label element. It is a well-meaning addition that helps discoverability – many people are not aware that label text should be clickable.

There is a problem with that however, since not all browsers make labels clickable (Safari only started doing it in version 3, for instance). If the cursor changes to a pointer over a label it looks like the label is clickable, but when you click it nothing happens. My experience tells me that can be quite confusing. Sure, this is not a huge problem, but I still tend to leave the cursor alone for labels.

I hope this helps explain how the label element works and encourages some people to use it more.

Posted on November 19, 2007 in (X)HTML, Accessibility