Skip to main content

Accessible Forms

Basics

  1. Forms should be logically structured, should be keyboard accessible, and should include instructions about requirements and the information being sought. 
  2. Associate a label with every form input.
  3. If a label must be hidden, use CSS to visually hide the label, while retaining the markup for screen readers.
  4. Use <fieldset> (with legends) to wrap related form controls together.
  5. Use <optgroup> to visually break up long lists of select options.
  6. If an image is used for a submit button, ensure that a text equivalent is provided.
  7. When a field is required, clearly indicate this inside the label.
  8. Provide informative, apparent and accessible error messages.
  9. Ensure that form help tips and instructions are accessible to screen readers.

In depth

Everyone benefits from well-organized, easy-to-use forms.  But it is especially essential for people who use screen readers and screen magnification andwho navigate websites using a keyboard. Without carefully planned and marked up forms, many of these users cannot access online forms.

Labels

Every form input must be associated with a label. There are two ways to associate labels with form inputs:

The first is to provide matching FOR and ID values for each label-input pair:

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

The second is to wrap both the label text and the input in <label>...</label> tags:

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

Here's a textarea example:

<label for="message">Your Message:</label>
<textarea id="message" name="message"></textarea>

<label>Your Message: <textarea name="message"></textarea>

Here's a radio button example:

<label for="subscribe">Subscribe?</label>
<input type="radio" id="subscribe" name="subscribe" value="subscribe">

<label>Subscribe? <input type="radio" name="subscribe" value="subscribe"></label>

Hidden labels

Although not recommended, if you must hide a label due to design considerations, use a CSS method to visually hide the label, while retaining the markup for screen readers.

Example:

HTML:
<label for="search" class="visually-hidden">Search</label>
<input id="search" type="text" name="search">

CSS:
.visually-hidden {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
}

Alternately, form controls without labels can be identified by an ARIA-LABEL attribute. (See more on WAI-ARIA.)

Example:

<input id="search" type="text" name="search" placeholder="Search" aria-label="Search">

NOTE: Screen readers do not read placeholder text, so it should never be a replacement for a label.

Fieldsets and legends

Fieldsets wrap related form controls together. Legends describe the group and should be brief because screen readers repeat them for every field control.

Example with radio buttons:

<fieldset>
<legend>Choose a meal choice:</legend>
<input id="chicken" type="radio" name="chicken-dinner" value="chicken">
<label for="chicken">Chicken</label><br>
<input id="fish" type="radio" name="fish-dinner" value="fish">
<label for="fish">Fish</label><br>
</fieldset>

Example with text fields:

<fieldset>
<legend>Your address:</legend>
<label for="street">Street</label>
<input id="street" type="text" name="street">
<label for="zip">Zip Code</label>
<input id="zip" type="text" name="zip-code">
</fieldset>

Single checkboxes and simple pairs of radio buttons (Yes/No) do not need fieldsets and legends.

Select lists

Consider using <optgroup> to visually break up long lists of select options to make them more manageable. Optgroups provide non-selectable labels.

Example:

<label for="toppings">Select pizza toppings:</label>
<select id="toppings" name="pizza-toppings">
    <optgroup label="Meat">
        <option value="1">Pepperoni</option>
        <option value="2">Sausage</option>
        <option value="3">Bacon</option>
        <option value="4">Ham</option>
    </optgroup>
    <optgroup label="Vegetable">
        <option value="5">Onions</option>
        <option value="6">Green pepper</option>
        <option value="7">Mushroom</option>
        <option value="8">Olives</option>
     </optgroup>
</select>

Button images

If an image is used for a submit button, ensure that an equivalent text alternative is provided in the markup. Don't use Reset buttons because they are often accidentally clicked.

Example:

<input type="image" name="submitbutton" alt="Submit" src="submit.png">

Required fields

If a field is required, a clear indication of this should be included inside the label or by using an ARIA state. (See more on WAI-ARIA.)

Examples:

<label for="username">Username <span class="red">(required)</span></label>
<input  id="username" type="text" name="username"><label for="username">Username</label>
<input  id="username" type="text" name="username" aria-required="false">

Error messages

Error messages must be informative, apparent and accessible. The primary ways to meet this requirement are:

  • An error alert, followed by focus on the form
  • An error message displayed above the form
  • An inline error message displayed beside the relevant form control

See more on live regions and error messages in the WAI-ARIA guidelines.

Form field help text

Screen readers usually skip over any text in forms that is not inside a form element. Therefore, include help tips and instructions either at the beginning of the form, inside the form control's label, or in an aria-describedby attribute. (See more on WAI-ARIA.)

Example:

<label for="password">Create a password:</label>
<span id="pass-tip">Passwords must be 8-12 characters and can include letters, numbers
and symbols.</span>
<input id="password" type="password" name="new-password" aria-describedby="pass-tip"><br>

 

How to test

Many users navigate forms using the keyboard. Check that a form is keyboard accessible by ensuring that:

  1. You can move from one form control to the next using the tab key—in order and without skipping any controls.
  2. Select menus open, and options can be selected using the arrow key.
  3. Each control has a clear visual focus state.
  4. The input cursor is visible in text fields.
  5. You can use the space bar to select checkboxes and radio buttons.
  6. You can submit the form with the ENTER key.

Relevant W3C WAI documents

  • WCAG 2.1 Guideline 4.1.2 — Name, Role, Value: For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies. (Level A)
  • How to Meet WCAG 2.1 Guideline 4.1.2