Forms are the main way that our users interact with our products and sites. From sending a message to checking out, editing a profile to creating something new, wherever our users connect with our product, there is likely a form that makes it possible. Making forms more accessible means more people can use our products more easily. So how do we improve the accessibility of our forms? Choose the right tools for the information we expect, tell our users clearly what to do, and make it easy to enter.
New HTML5 attributes
Let’s start with choosing the right tools. HTML5 introduced useful new input types to expand upon the kind of data that form fields can gather. These new input types also have the added benefit of making it easier to use customized keyboards on touch devices, while simultaneously failing gracefully and accepting basic text input for older browsers that don’t support them.
In addition to new input types, HTML5 also introduced new attributes that can improve your form’s ease of use. These attributes include:
placeholderfor adding example values in the form field that are automatically cleared when the field is focused,
requiredto denote to the browser when a field must be filled out,
patternto allow developers to define a specific pattern that field data should match,
autofocusfor automatically placing the cursor in a specific field when the page loads, and
autocompletewhich allows the browser to automatically fill information in a field. (Note: this is on by default so you really only need to use it when you want to disable autocomplete for a field.)
These new attributes add extra information about your form to help browsers and devices better assist your users in filling them out. Even if you’re not coding the UI yourself, being aware of these new types and attributes can help you recommend the right options for each field.
Labels are your friend
Once you’ve settled on the appropriate input type and added helpful attributes, it’s time to give your form field helpful guidance. And that starts with
<label>s. Labels tell your users what content you expect in each form field.
A basic label can take two forms: either by containing both the input and the label text, or adding a
for attribute to the label that matches an
id on the corresponding
<input>. While both methods will work fine, it’s a good habit to add the matching
id attributes even in the containing method. (It’s also important to keep in mind that
id attributes need to be unique.)
<label for="email">Email</label> <input type="text" id="email" name="s_email"> <label for="optin"> <input type="checkbox" name="s_optin" id="optin" value="yes"> I would like to opt in to receive the weekly newsletter. </label>
Adding labels to fields — in particular checkboxes and radio buttons — also increases the clickability of those fields. Instead of having to click only on the checkbox or radio button, for instance, your users will now be able to select them by clicking on the label as well.
Labels are obviously important for complex forms with many fields, but it can be tempting to skip labels for simpler forms (like search and subscription forms which are often a single field). While you may not want a visible label for these fields, it’s still important to include context. Luckily, you can use ARIA attributes to add a hidden label or to label your field using the content of another element.
In the first example below, the
aria-label attribute adds a hidden label that will only be read by screen readers to give additional context to the field. (The biggest downside of this method is that some translation tools will not translate text within the
aria-label attribute like they will for other methods.)
<input type="text" name="email" aria-label="Email address">
In this second example, you can use the
aria-labelledby attribute to use text from another element as a label by referring to that element’s ID. Using this method, you can even label an input by referencing multiple elements, simply by adding each element’s ID separated by a space. (You could, for instance, use this to label form fields inside a table by data from both the column and row headers).
<input type="text" name="q" aria-labelledby="s_enter"> <input type="submit" id="s_enter" value="Search">
The best practice is to use visible labels whenever possible as they tell all of your users what data you expect. When the surrounding content is redundant or the form is simple and straightforward, you can use the above methods for a cleaner experience.
Placeholders gonna placehold
You may be tempted to use placeholders to replace labels. Please don’t! Placeholders are meant to serve a different purpose. According to the W3C (the World Wide Web Consortium, who create the HTML standards), the placeholder attribute should “represent a short hint (a word or short phrase) intended to aid the user with data entry.” It should be short so that the entire placeholder is visible within the input field without getting cut off.
Why shouldn’t you use a placeholder in place of a label? Once the user focuses on the field or adds any data, the placeholder’s purpose is fulfilled and it disappears, leaving the user with no context. In addition, the default style for placeholder text is much lower in contrast, making it hard to read for many users.
Best of both worlds?
Like the placement of a placeholder, but want something a little more dependable? The float label pattern can give you a slightly cleaner form field, with the label overlapping the field and looking like a placeholder. When the user focuses on the field, the label slides up (or down) so it’s not obscuring the field. This method provides a more persistent context but cleans up the layout so label and field appear as one entity until edited.
Going deeper with aria-describedby
There will be times when a form field needs more supplementary help info than is best contained in a simple label. Maybe it’s a password field with a longer description of the password rules. Or perhaps a text area where you want to provide some additional guidance on what to write. You can add the
aria-describedby attribute to the field and set its value to the ID (or multiple space-separated IDs) of an element that describes the field.
<label for="pw">Password</label> <input type="password" aria-describedby="pw-rules" id="pw" name="password"> <div id="pw-rules"> Your password must: <ul> <li>be at least 8 characters in length</li> <li>have both upper- and lowercase letters</li> <li>contain at least 2 numerals</li> <li>contain at least 1 special character (& % $ # @ ? -)</li> </ul> </div>
In case of error
Everyone makes mistakes, and there will be times when you need to let your users know they’ve made one. There are two common approaches to error handling in forms: notifying users as they edit the form and notifying them after submission. Both options can be done accessibly using slightly different methods.
There are a couple helpful ARIA attributes that can add useful data to your form fields to improve their accessibility for both methods:
aria-required: This attribute denotes that a field is required. The default value is false. When set to true, screen readers should notify users that the field is required.
aria-invalid: This attribute notes when a field has an error. The default value is false. Other possible values include true, spelling, and grammar. Assistive user agents should alert users when the field is set to any value other than false.
You can use the
aria-describedby attribute to tie an invalid field to a specific error message. This way, when the user focuses on that field in a screen reader, it will be able to notify the user of the error properly. Here’s an example of how you might make an error message for a required email address more accessible:
<label for="f_email">Email address</label> <input type="email" name="email" id="f_email" required aria-required="true" aria-invalid="true" aria-describedby="email_error"> <div id="email_error"> Please provide a valid email address. </div>
The above example works when showing an error after submitting the form. When processing errors as the user edits the form, however, you should add a couple additional ARIA attributes to the error message itself so that screen readers will notice when it changes. Setting the
aria-role attribute to
alert tells assistive software that the element may change and that the user should be notified when it does. In addition, the
aria-live attribute lets you specify how assistive technology should announce those changes. Setting it to
polite should wait until the user has finished with their current task. Using
assertive instead will interrupt the current task. (Support for various settings of the
aria-live attribute in screen readers seems to vary so be sure to test for yourself.)
<div aria-role=“alert” aria-live=“polite” id=“email_error”> Error Message </div>
Functional form tips
- Use descriptive labels, placeholders, and help text with form fields.
- Wrap radio inputs and checkboxes along with their labels so that users can click not only the box/radio input, but also the text related to it.
- For a more “minimal” form field, consider the float label pattern. Otherwise use
aria-labelledbyto add context.
aria-describedbyto tie longer descriptions to form fields when needed.
- Write clear error messages, and use the appropriate ARIA attributes to place them in context.
Become a design a11y
Now you know how to create more accessible forms. Explore how other aspects of design can improve the accessibility (and overall usability) in the Design A11y series below:
- Designing for Accessibility: An Introduction
- Color and Contrast
- Content and Context
- Navigation and Interaction