Form Labels: Visible And Hidden

This post originally appeared on the Yahoo! Accessibility blog.

What are form labels

Each input on your form needs a label. Yes, that includes radio buttons, check boxes, and file uploads. Labels tell people what an input expects. They also provide larger targets for those with less motor control.

Connecting the label and input

Fortunately labels are easy to use. There are two ways to connect the label to an input: Belt and Buckle.

The belt method (implicit association) wraps the input in a label.

<label>First Name <input type="text" name="fname"></label>

The buckle method (explicit associtation) connects the label via the input's id value

<label for="firstname">First Name</label>
<input type="text" name="fname" id="firstname">

While the belt method is simpler, it doesn't provide as much flexibility with layout. It also fails to set focus on the input in Internet Explorer 6 and may not work with all versions of Window Eyes screen readers. It's also possible to combine the methods.

Hidden Labels

Up to this point we are assumed the labels will be visible. There are times when we want the label to be invisible, due to visual space in the layout.

The following form has a hidden label for the search input. Form with hidden labelForm with hidden labelIt uses the CSS clip property to hide the label. It's still available to screen readers.

Do not use "display:none" or "visibility:hidden" to hide form elements. This will also hide them from screen readers.

<label for="p" class="obscure">Enter a search term</label>
<input type="text" id="p" name="p">
<input type="image" src="" alt="search">

The "obscure" class uses a clipping technique to hide the label from the visual design. However, it is still available to screen readers and will not trigger problems when localizing the site with a right to left language, such as Arabic. Get more information on this technique at: Clip your hidden content for better accessibility .

.obscure {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);

Use ARIA to label inputs

You can use the ARIA labelledby or label attributes to add the same functionality without the additional markup and CSS. Use aria-labelledby to point to some text that describes the input. Use aria-label to include the text directly in the input. These aria attributes do not replace the optional value or placeholder attributes.

The aria-labelledby attribute works especially well when you have multiple form inputs on a page that could share the same text description.

<legend id="dirsearch">Directory Search
<p>blah blah blah</p>
<input type="text" name="p">
<input type="image" src="" alt="search">

If the label text is visible on screen, authors SHOULD use aria-labelledby and SHOULD NOT use aria-label. Use aria-label only if the interface is such that it is not possible to have a visible label on the screen. User agents give precedence to aria-labelledby over aria-label when computing the accessible name property.

The aria-labelledby attribute is very similar to describing an object with aria-describedby, where a description is intended to provide additional information that some users might need.
Supported States and Properties: aria-labelledby - W3C

The aria-label defines a string value that labels the input. It should only be used when the text is hidden.

<input type="text" name="p">
<input type="image" src="" alt="search">

What you can do

Form labels are critical for making your forms accessible. Make sure your users know each input is expecting as an answer. The label tag also provides a larger target for users to click on. Use ARIA when you are not able to use the label tag.

  • Use the label tag for your forms to make them accessible and easier to use.
  • Use the clip pattern to hide label tags when they are not part of the visual design
  • Use ARIA labelledby or label attributes instead of the label tag when necessary.
  • Use an alt attribute whenever you use input type="image". The alt text will override the input's label in JAWS.