Skip to content

Forms

Making accessible forms is easier than you may think. It boils to just a few main concepts:

  1. Labels on every form input
  2. Labels for groups of inputs
  3. Clear instructions
  4. Error prevention
  5. Form validation

Labels

Labels MUST be programmatically associated with their corresponding elements.

Every form input needs a label, also known as an "accessible name," which we've seen previously in the accessibility tab in the developer tools.

There is a hierarchy of methods for providing an accessible name for input.

  1. aria-labelledby
  2. aria-label
  3. <label> - Recommended method for most circumstances
  4. <title>
  5. placeholder - Strongly discouraged!

As you see, using the <label> element is recommended, and what you learned to use in the Website Development course. The <label> can be implicitly or explicitly defined. In both cases, the label should describe the purpose of the field.

Explicit Labels

The <label> element uses the for attribute to associate it with the input field. The for attribute takes the value of the input id.

<label for="firstName">First name:</label>
<input type="text" name="firstName" id="firstName">

Implicit Labels

To label fields implicitly, the <label> element is used as a container for the input field. Generally, assistive technology supports explicit labels better, so this method should be avoided if possible.

<label>First name:
  <input type="text" name="firstName">
</label>

aria-label

You can use the aria-label attribute to label form controls. Remember that no visual content will be conveyed to visual users, so only use this when the surrounding content gives a clear indication of what should be entered for visual users. Below is one of the few circumstances where it is permissible not to have a visible label for a form field.

<input type="text" name="search" aria-label="Search Courses">
<input type="submit" class="myButton" value="Search Courses">

aria-labelledby

Similar to the aria-label attribute, the aria-labelledby attribute can be used to identify form controls. The difference is that aria-labelledby uses the id of the form control to get the label. It also overrides any explicit or implicit labels.

<input type="text" name="search" aria-labelledby="searchbutton">
<input id="searchbutton" type="submit" class="myButton" value="Search Courses">

Label Text

Labels MUST be available as programmatically determinable text.

Labels must contain text that assistive technologies can read. Therefore, an empty label element, icons, or pictures cannot be used as a label.

Labels MUST be meaningful.

Labels must be clear, informative, accurate, and meaningful.


Visual Characteristics

Labels MUST NOT rely solely on references to sensory characteristics.

  • If color is used on a form label, ensure non-color distinguishing features are present, such as text, symbol, or icon.

  • The color contrast of text, symbols, or icons used as labels must meet minimum color contrast ratio requirements.

  • All visual information must be provided programmatical for AT users.

In the below example, the icon with the lowercase "i" signifies additional information. But, the label provided only says "button," which is not helpful for a screen reader user.

<label for="hue">Favorite hue:</label>
<input type="text" id="hue" class="a11y"> 
<button aria-label="button" onclick="alert('Hue is another word for color');">
    <span class="fa fa-info-circle"></span>
</button>

The below label is more meaningful.

<label for="hue">Favorite hue:</label>
<input type="text" id="hue" class="a11y"> 
<button aria-label="What does hue mean?" onclick="alert('Hue is another word for color');">
    <span class="fa fa-info-circle"></span>
</button>

Placeholder Text

Placeholder text MUST NOT be used as the only method of providing a label for a text input.

Placeholder text is a nice visual way to display information to the user. However, it is not read by some screen readers and should NEVER be the only label provided. Not only that, they can be difficult for visual users because as soon as text is entered into the field, the placeholder text disappears!

Placeholder Contrast

Unfortunately, the color that is rendered by placeholder text does not meet the minimum contrast requirement. The change is very subtle, but this code makes it WCAG AA compliant.

input::placeholder {
  color: #767676;
}

Positioning Labels

A label SHOULD be visually adjacent to its corresponding element.

If labels are too far away from their corresponding form field, people using screen magnification may have trouble finding them or may have to scroll back and forth to make the connection between the form fields and their labels.

There are three common ways to align form fields on the page.

Top-aligned

Most research suggests that using top-aligned labels results in the quickest completion times, the least user confusion, and the least amount of extraneous eye movement. Additionally, it reduces the amount of horizontal scrolling the user may have to do.




The Good The Bad
Best completion rates Requires more vertical space
Best for multi-language support* Not ideal for very long forms

* Multi-language support: This allows for different label lengths when the form is translated into other languages.


Left-aligned

Provides the easiest method of quickly scanning all the label values. This alignment can be helpful when the form is asking for unusual data, and the form needs to be clearly understood. However, research shows they have the slowest completion times. This is due to the visual distance between the label and the input field.

The Good The Bad
Requires less vertical space Requires more attention from users
Easy to scan labels Slowest completion rates
Poor multi-language support

Right-aligned

Right-aligned labels are similar to left-aligned labels. However, this is a stronger visual connection between the label and the input field. That being said, the jagged left edge makes it uncomfortable to look at and harder to read.

The Good The Bad
Best visual connection between labels and forms Hardest to read and scan
Good completion rates on short, familiar forms Poor multi-language support
Requires less vertical space

Grouping Controls

Group labels MUST be programmatically associated with the group if the individual labels for each element in the group are insufficient on their own.

<fieldset> and <legend>

Grouping input fields make forms more understandable to all users. Placing related content into small manageable chunks reduces information overload, especially on long forms. In the Website Development course, you learned how to use <fieldset>, <legend>, and <select> to group content.

Like other labels, the <legend> must be meaningful, cannot rely solely on sensory characteristics, and is must be visible.

Choose an Output format

<fieldset>
  <legend>Choose an Output format</legend>
    <input type="radio" name="format" id="txt" value="txt">
    <label for="txt">Text file</label><br/>
    <input type="radio" name="format" id="csv" value="csv">
    <label for="csv">CSV file</label><br/>
    <input type="radio" name="format" id="html" value="html">
    <label for="html">HTML file</label>
</fieldset>

The below example is not accessible. Even though items appeared grouped, the screen reader would not be able to convey the information to the user.

Choose an Output format



<div class="group">
  <h4>Choose an Output format</h4>
    <input type="radio" name="format" id="txt" value="txt">
    <label for="txt">Text file</label><br/>
    <input type="radio" name="format" id="csv" value="csv">
    <label for="csv">CSV file</label><br/>
    <input type="radio" name="format" id="html" value="html">
    <label for="html">HTML file</label>
</div>

<select> Menus

The <select> element groups <option> elements included in a dropdown list. The native HTML provides enough context for the screen reader, including how many items are in the dropdown.

<label for="state">Select a state:</label>
<select name="state" id="state">
  <option value"00">--select--</option>
  <option value"WI">Wisconsin</option>
  <option value"MI">Michigan</option>
  <option value"MN">Minnesota</option>
  <option value"OH">Ohio</option>
  <option value"IL">Illinois</option>
</select>

Form Instructions

Help users avoid making errors by providing clear instructions and helpful information. Generally speaking, you should:

  • Ensure labels and instructions are clear and informative.
  • Make instructions and advisory information available to assistive technologies.
  • Clearly disclose constraints for form fields.
  • Clearly identify required form fields.

Instructions for Groups

Having regular, paragraph-like text in the middle of the form runs the risk that screen readers will not hear it. Users tabbing through focusable elements will skip over all non-focusable text unless that text is programmatically associated with a group label or input.

One solution is to use aria-describedby to add content to the default label.

Passwords must match and contain one special character

<label for="username">Username:</label>
<input type="text" id="username" name="username" class="a11y">

<p id="passwordInfo">Passwords must match and contain one special character</p>

<label for="password">Password:</label>
<input type="password" id="password" name="password" class="a11y" aria-describedby="passwordInfo">

<label for="password-2">Re-enter Password:</label>
<input type="password-2" id="password-2" name="password-2" class="a11y">

🤔 Take a moment to look at how the above form is designed. What simple change could you make to the UI to improve the UX?

Hint: It has to do with spacing.


Instructions with multiple form fields.

Login Information (Required)

Must not contain spaces



<fieldset>
<legend>Login Information (Required)</legend>
  <p id="mustnot">Must not contain spaces</p>
  <label for="usernameExample">Username: </label> 
  <input type="text" id="usernameExample" aria-describedby="mustnot" required class="a11y"><br><br>
  <label for="passwordExample">Password: </label> 
  <input type="password" id="passwordExample" aria-describedby="mustnot" required class="a11y">
</fieldset>

🤔 What about this form? What simple change could you make to prevent errors?

Hint: It has to do with text content.


Instruction placement

Instructions for groups or sections SHOULD be visually adjacent to the grouped elements.

Not only is it helpful for everyone when instructions are near the form field, or the form itself, it helps users that use screen magnification.

As a general rule, all form instructions should be included before the <form> element.


Required Fields

Required fields SHOULD be programmatically designated as such.

You can programmatically set required fields with the required HTML attribute and the aria-required="true" attribute.

aria-required="true"

Setting aria-required="true" on an input is an unambiguous way to designate the field as required. Screen readers say "required" after reading the input's label. This attribute is invisible, though, so you will need to supplement it with other methods that sighted users can see.

HTML 5 required

The HTML 5 required attribute sounds the same to screen reader users — they hear "required" after the input's label — but the HTML 5 attribute adds a browser behavior (in browsers that support it): it prevents users from submitting the form if there are errors. That can be a good thing in theory, but not all browsers support it, and this takes away some of your freedom to design the error handling behavior, so use this very cautiously. Also: it's invisible; sighted users can't see it.

Required HTML Field







<form action="http://itins3.madisoncollege.edu/echo.php" method="post">
  <label for="name">First Name</label>
  <input type="text" id="name" name="name" class="a11y">

  <label for="city" class="required">City (required)</label>
  <input type="text" id="city" name="city" required aria-required="true" class="a11y">

  <input type="submit" class="myButton" >
</form>

🤔 How do you use the required attribute on the <select> (dropdown) field? It's a little more complicated than the above example.

Here is a great article explaining how:

Using the required attribute with the select element

Or, check out my required select example above.


Visual Indicator

Required fields SHOULD have a visual indicator that the field is required.

It's necessary to indicate what fields are required, optional, and valid data formats to the user. This information should not solely be visual (red text for required fields). Instructions need to be in a format that screen readers can access.

If you use an asterisk to denote required fields, you must explain what the asterisk is referring to. Such as, "Fields with asterisks (*) are required."


Radio vs Dropdown Menus