Forms: accessibility for developers

  • Author: Access iQ ®
  • Date: 1 Feb 2013
  • Access: Premium

Quick facts

Form requirements must be made clear for people with disabilities, so they can equally participate in the activities the form was designed for.


  • Explicitly associate form labels with their input fields
  • Associate form controls with the title attribute if a label cannot be used
  • Group form labels together visually
  • Use fieldset and legend to create semantic structure

The longest running method for users to interact with websites has been through the input elements in HTML forms, officially a part of HTML since 1995's HTML 2.0. It is the simplest way for users to provide information and to interact with automated systems. In contrast to simple actions a user may take like following links, forms allow a website to collect data from a user, restrict qualities of that data to specific parameters and to do something with that data, in the browser, on the server, or both.

For people to use forms, it must be made clear what the form requires of them. The requirements must also be made clear for people with disabilities, so they can equally participate in the activities the form was designed for. Fortunately, HTML has elements that contribute to accessible forms and screen readers are adept at parsing the context and semantic meaning of these elements to users.

This topic discusses several basic components of a form and how to make them accessible.

Form labels

Form labels are important because they explain the purpose of various form elements to the user and were introduced with HTML 4 in 1997. For example, a label for a textbox tells the user what information they should enter within the box, or what option they are selecting via a radio button.

Success Criterion 2.4.6 Headings and labels states:

Headings and labels describe topics or purpose.

If a form element doesn't have a form label, users will not be certain what to enter into the field. It has been common practice in the past to place text visually near form fields to help users know what to enter, but this is not the same as using the HTML label element. They may visually appear the same but they are semantically very different.

When a label is displayed on the screen, it is usually positioned close to its corresponding form element, making the association between the label and the form element visually apparent for a sighted user. For a person using assistive technology such as screen readers or refreshable Braille display, it is important that this same association is communicated in a way that is accessible, using HTML elements for semantic markup and text for screen readers to understand.

There are two techniques for associating form labels with their form controls to ensure accessibility:

  1. By explicitly associating form labels with their input fields using the label element; or
  2. By associating form controls with the title attribute when the label element cannot be used.

The preference is to use text within a label element, referencing the id attribute of the element within the form. For example:

<label for=”pass”>password</label>

<input type=”password” id=”pass” name =”pass” />

However, if a design will not accommodate a label or where it may be confusing to display a label, then the technique that associates form controls with the title attribute will be applicable.

Explicitly associate labels with their input fields

When a form label is visibly displayed to the user, the form label must be explicitly associated with an element to ensure assistive technologies like screen readers and refreshable Braille displays can communicate form controls.

Explicitly associating a form control requires the for attribute of the label element and the id attribute of the input element to have the same value. As the label will be read by a screen reader, and references an id attribute, both the label text and the id value should be unique for each page presented to the user.

Example of an explicit association of a label with the input element:

<label for="firstname">First name:</label>

<input type="text" name="firstname" id="firstname" />

A label references an element by matching its for="" attribute with the input element's id="" attribute. Use the label element with the following form elements:

  • input type="text"
  • input type="checkbox"
  • input type="radio"
  • input type="file"
  • input type="password"
  • textarea
  • select

Instructions for explicit association of form labels with form controls:

  1. Associate the label element with the form element using the for attribute.
  2. The value of the for attribute must be the same as the value of the id attribute of the form control.
  3. The value of the id attribute and the name attribute must be provided. These values may be the same.
  4. The value of the id attribute must be unique in the document.

Example of a simple form:

<form action="http://accessiq.org/process_form.php" method="post">

<label for="firstname">First name:</label>

<input type="text" name="firstname" id="firstname" />

<label for="lastname">Last name:</label>

<input type="text" name="lastname" id="lastname" />

<input type="radio" name="gender" id="male" value="male" />

<label for="male">Male</label>

<input type="radio" name="gender" id="female" value="female" />

<label for="female">Female</label>

<input type="checkbox" id="all" name="newsletter" value="all">

<label for="all">All news</label>

<input type="checkbox" id="tech" name="newsletter" value="tech">

<label for="tech">Technology news</label>

<input type="checkbox" id="enviro" name="newsletter" value="enviro">

<label for="enviro">Environmental news</label>

<input type="submit" value="Apply"/>

</form>

There is an additional method for labelling form fields, by using the aria-labelledby attribute with the input element.

For example:

<label for="firstname" id=”fnameLabel”>First name:</label>

<input type="text" name="firstname" id="firstname" aria-labelledby=”fnameLabel”/>

Screen readers that support ARIA will use the ARIA label. Those that do not will ignore the ARIA label and go straight to the HTML label.

Associate form controls with the title attribute if a label cannot be used

There are times when a label isn't visible within the design. It may be unnecessary, it may not fit with the visual design or it might be confusing if the label is displayed. Examples include a search box where a button labelled "Search" appears immediately after the search box, where form elements appear in a table, or where there are multiple input fields for a phone number (country code, area code and phone number). It must be noted that some of these conditions can be considered difficult to use or badly formatted HTML.

If a label cannot be used, then the title attribute must be used to label form controls. If there is no label element present, then a screen reader will read out the contents of the title attribute instead, ensuring that the form element is accessible.

Example 1 below has an input with a clear description of the purpose of the input, followed by the button clearly labelled "Search" so that the user understands the action required.

Example 1:

<input type="text" title="Type search term here"/> <input type="submit" value="Search"/>

The attribute aria-labelledby can be used by elements other than label, as in:

<h1 id=”listHeader”>My favourite things</h1>

<div role=”list” aria-describedby=”listHeader”>

<div role=”listitem”>coffee</div><div role=”listitem”>chocolate</div><div role=”listitem”>cake</div>

</div>

Grouping form elements

One of the reasons forms may be inaccessible to people with some kinds of disabilities is that the presentation of the forms visually establishes relationships between the form elements, which may not be communicated when processed by a screen reader.

Success Criterion 1.3.1 Info and relationships states:

Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text. (Level A)

In the case of forms, this means that the relationship between a form element such as a text field and the description or name of that field — which may be perfectly evident visually — must be marked up so that the relationship is equally evident to someone using a screen reader.

This principle extends to the way sets of form elements might be grouped visually into thematic sections. Those groupings, which may assist the user to understand and complete the form, should be marked up so that they are accessible to a screen reader.

There are two suggested Techniques for using HTML to help meet Success Criterion 1.3.1:

Using fieldset and legend

Enclosing your form items within a fieldset element will semantically group those elements together. To continue a good semantic structure, use the legend element immediately inside the fieldset to give it a name or description. You may think of the relationship between fieldest and legend similar to input and label, where the latter is a descriptive label for the former.

<form action="" method="post">

<fieldset>

  <legend>Your Details</legend>

  <label for="firstname">First name:</label>

  <input type="text" name="firstname" id="firstname" />

  <label for="lastname">Last name:</label>

  <input type="text" name="lastname" id="lastname" />

</fieldset>

<fieldset>

  <legend>Your Newsletters</legend>

  <input type="checkbox" id="all" name="newsletter" value="all">

  <label for="all">All news</label>

  <input type="checkbox" id="tech" name="newsletter" value="tech">

  <label for="tech">Technology news</label>

  <input type="checkbox" id="enviro" name="newsletter" value="enviro">

  <label for="enviro">Environmental news</label>

</fieldset>

<input type="submit" value="Apply"/>

</form>

By default, this will place a border around the grouped form elements on the webpage, with the contents of the legend element superimposed on the top border.

A form with two fieldsets, where the first fieldset is labelled "Your Details" and has two form fields, and the second is labelled "Your newsletters" and has three checkboxes.

Note: Not all browsers render fieldset in the same way. However, in all cases, you can use cascading style sheets (CSS) to style the visual features to suit without affecting the semantic characteristics. Specify your preferred border property of fieldset, and the position property of legend.

If the form you are developing is already designed to have sections with descriptive titles, it is not necessary to use fieldset as well. You should ensure, however, that the form controls have appropriate label elements.

A good use of fieldset is to group checkbox or radio button input elements in a single form question. Each option within the fieldset should have the same name value, if they are options of the same question.

<form action="" method="post">

<fieldset>

  <legend>I own these devices (check all that apply):</legend>

  <input type="checkbox" id="desktop" name="devices" value="DT">

  <label for="desktop">Desktop</label><br />

  <input type="checkbox" id="laptop" name="devices" value="LT">

  <label for="laptop">Laptop</label><br />

  <input type="checkbox" id="tablet" name="devices" value="TB">

  <label for="tablet">Tablet</label><br />

  <input type="checkbox" id="phone" name="devices" value="PH">

  <label for="phone">Phone</label>

</fieldset>

<input type="submit" value="Submit"/>

</form>

This renders as:

A form using the fieldset element to group checkboxes with a label "I own these devices (check all that apply):" and checkbox items Desktop, Laptop, Tablet, Phone.

Nesting the fieldset element

Some forms are long and complicated enough to warrant not only being divided into sections but sub-sections as well. This can be mirrored programmatically by nesting groups using the fieldset element.

<form action="" method="post">

<fieldset>

  <legend>Your Address</legend>

     <fieldset>

       <legend>Residential</legend>

       <label for="raddress1">Street Address: </label>

       <input type="text" id="raddress1" name="raddress1" />

       <label for="rcity">City or suburb: </label>

       <input type="text" id="rcity" name="rcity" />

       <label for="rstate">State: </label>

       <input type="text" id="rstate" name="rstate" />

       <label for="rcode">Postcode: </label>

       <input type="text" id="rcode" name="rcode" />

     </fieldset>

     <fieldset>

       <legend>Postal</legend>

       <label for="paddress1">Postal Address: </label>

       <input type="text" id="paddress1" name="paddress1" />

       <label for="pcity">City or suburb: </label>

       <input type="text" id="pcity" name="pcity" />

       <label for="rstate">State: </label>

       <input type="text" id="pstate" name="pstate" />

       <label for="pcode">Postcode: </label>

       <input type="text" id="pcode" name="pcode" />

   </fieldset>

</fieldset>

<fieldset>

  <legend>Your Name</legend>

  <label for="firstname">First name:</label>

  <input type="text" name="firstname" id="firstname" />

  <label for="lastname">Last name:</label>

  <input type="text" name="lastname" id="lastname" />

</fieldset>

<input type="submit" value="Apply"/>

</form>

This renders as:

A long form that is divided into sections and sub-sections by nesting groups using the fieldset element.

Avoid using too many fieldsets on one form so that the webpage doesn't become too complicated. The site will be read out linearly using a screen reader and therefore be too complex to understand clearly if there are too many nested elements. Fieldset nesting more than two deep is hard to justify.

Using the optgroup element

The select element also provides means to group several option elements together via the optgroup element. It provides a non-selectable label to a group of options where the collection of option elements are grouped within the optgroup element, and labelled by the optgroup element's label attribute. This allows screen readers to describe the groupings accurately. Be advised, however that the optgroup is not consistently supported across all screen readers.

<form action="" method="post">

    <label for="city">What is your target city?</label>

    <select id="city" name="city">

      <optgroup label="Victoria">

        <option value="1">Melbourne</option>

        <option value="4">Geelong</option>

        <option value="5">Shepparton</option>

      </optgroup>

      <optgroup label="New South Wales">

       <option value="2">Sydney</option>

       <option value="6">Newcastle</option>

       <option value="7">Wollongong</option>

      </optgroup>

      <optgroup label="Queensland">

       <option value="3">Brisbane</option>

       <option value="8">Gold Coast</option>

       <option value="9">Townsville</option>

      </optgroup>

    </select>

</form>  

This will render as:

A dropdown menu with "Victoria" in bold and "Melbourne", "Geelong" and "Shepparton" indented under "Victoria", and two other groups of options formatted in the same way.

Note: Support for the optgroup element is limited among older screen readers.