WCAG – 3.3.2 Labels or Instructions (Level A)

3.3.2 Labels or Instructions: Labels or instructions are provided when content requires user input. (Level A)

Requirements

Labels

  • All labels in a form clearly and precisely describe the data required from users;
  • Radio buttons and checkboxes are correctly grouped and associated with a group label.

Required fields

  • Fields that are mandatory are clearly indicated (for example with the text “Required”).
    • Alternatively, the labels of non-mandatory fields include the text “(Optional)” when most fields are mandatory.

Additional instructions

  • Additional instructions are provided for fields that require data to be entered in a specific format.
    • Instructions should be included in the label or displayed next to the field;
    • Instructions should be properly associated in code with the relevant form field.

Why is it important?

This ensures that everyone understands any requirements for entering data, and that screen reader users are made aware of it.

  • Labels help all users to understand what a form control is and what is being asked for. And they are essential for users who cannot easily determine this by looking at the form and surrounding content.
  • Correctly grouped radio buttons and checkboxes help all users understand the relationships between those options. It also makes standard keyboard support for navigating radio buttons work out of the box (for Web).

Summary

  • Provide labels to make it clear how users should fill in a form, and optionally provide extra hints to help them avoid errors.
  • Form elements (like a text input field or a checkbox) should have clear labels and instructions.

Common mistakes

  • Data is expected in a specific format, but no instructions have been provided;
  • Instructions have been provided, but they are not associated with the relevant field.

Design Guide

  • All form controls, such as text inputs, check boxes, select lists, or buttons, must each have a unique label that stays visible.
  • Don’t use text placeholders as a replacement for the label of text inputs, or to give additional instructions. This is because:
    • Placeholder text disappears as soon as text is entered in the field. This makes it impossible for users to check whether they’ve entered text in the right way.
    • Placeholder text doesn’t have enough contrast;
    • Placeholder text makes it hard at a glance to see that a text input field needs filling in;
    • On the Web, the placeholder attribute doesn’t reliably provide input elements with an ‘Accessible Name’.

Examples for Android

For text inputs, you can use TextInputEditText wrapped in a TextInputLayout:

<com.google.android.material.textfield.TextInputLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:hint="@string/form_username">

     <com.google.android.material.textfield.TextInputEditText
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>

 </com.google.android.material.textfield.TextInputLayout>

Using TextInputEditText instead of an EditText provides accessibility support for the text field and allows TextInputLayout greater control over the visual aspects of the text field.

Note: The hint should be set on the TextInputLayout, rather than the EditText.

Alternatively, you could use the labelFor attribute for connecting the EditText view with its label:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/email_subject_label"
    android:labelFor="@id/email_subject" />

<EditText
    android:id="@+id/email_subject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Defining an android:contentDescription on any EditText or editable TextView may interfere with an accessibility service’s ability to describe, navigate, and interact with text that a user enters within the item. It is not advisable to do this.

Examples for Flutter

For TextField type widgets you can use the InputDecoration() class to add labels and hints to the widget.

child: TextField(
  validator: (value) {
      // validation logic
      return null;
  },
  decoration: InputDecoration(
    hintText: String, // optional hint parameter
    labelText: String, // optional label parameter
  ),
),

Examples for Web

Associating a label with an input

<label for="uname">Username:</label>
<input type="text" id="uname" />

Failure example:

<!-- Don't do this -->
<div>
  Username: 
  <input type="text" id="uname" />
</div>

Associating a hint with a text input field using aria-describedby

<label for="national-insurance-number">
  National Insurance number
</label>

<span id="national-insurance-number-hint">
  It’s on your National Insurance card, benefit letter, payslip or P60. For example, ‘QQ 12 34 56 C’.
</span>

<input id="national-insurance-number" name="national-insurance-number" type="text"
aria-describedby="national-insurance-number-hint national-insurance-number-error">

<span id="national-insurance-number-error">
  <span class="visually-hidden">Error:</span> Enter a National Insurance number in the correct format
</span>

Grouping radio buttons and checkboxes together in a fieldset with a legend

  • Ensure that input type="checkbox" and input type="radio" elements that are related are grouped in a labelled container such as fieldset with legend.
  • Ensure all radio buttons in a group have the same name attribute.

Example:

Correct use of name attribute ensures checking one radio button will uncheck the other:

<fieldset>
  <legend>Would you like to receive email updates?</legend>
  <input name="rg1" type="radio" id="r1" value="yes"/>
  <label for="r1">Yes</label>
  <input name="rg1" type="radio" id="r2" value="no"/>
  <label for="r2">No</label>
</fieldset>

Failure example:

Incorrect use of the name attribute prevents correct keyboard access to radio buttons:

<!-- Don't do this -->
<input name="r1" type="radio" id="r1" value="yes"/>
<label for="r1">Yes</label>
<input name="r2" type="radio" id="r2" value="no"/>
<label for="r2">No</label>

If you’re not using standard HTML checkboxes or radio button controls, make sure that you closely follow the ‘Radio Group’ pattern in the ARIA Authoring Practices Guide, and test with one or more screen readers.

References

  1. Text input component and guidance in the GDS Design System
  2. Form Instructions tutorials by the W3C Web Accessibility Initiative.
  3. Basic form hints article on MDN.
  4. Using aria-describedby to provide form hints by Léonie Watson and The Paciello Group.
  5. Practical Support: aria-label, aria-labelledby and aria-describedby section in the W3C’s Using ARIA document.
  6. ‘Radio Group’ pattern in the ARIA Authoring Practices Guide
  7. Accessibility Guidelines- Github.io