Anatomy of accessible forms best practices labelled with best practices listed in blog post

The Anatomy of Accessible Forms: Best Practices

When we complete a task independently and successfully, the exhilaration is boundless. Filling forms on websites and apps for people with disabilities and even for people without disabilities carries with it a feeling of independence, even if it is simple.

The other day, I was amazed when I encountered such a scenario on a travel site. Even though I am an assistive technology user with a limited motor ability and cognitive ability, I was able to fill in all the details on that travel site within five minutes! And guess what? Without any error! You know how?

It was all because the forms had descriptive labels that were visible at all times. The form marked all of the mandatory fields, provided instructions that were easy to follow, grouped relevant form fields that clearly defined the purpose of those fields, and used minimal placeholders that gave necessary hints. Above all, the form communicated the role, name and state of the form controls to the assistive technology that I was using.

In our last two posts, we discussed the ill-effects of using the placeholder attribute and how to mark-up required fields for accessibility. If you haven’t already, I recommend that you read my first two blog posts on accessible forms:

  1. The Anatomy of Accessible Forms: The Problem with Placeholders
  2. The Anatomy of Accessible Forms: Required Form Fields

In today’s post, we will go through all the ingredients of creating an accessible form that provides the best user experience for all users. We will go through each aspect of creating an accessible form, understand why a particular step is important, and how it affects people with disabilities or users in general.

Use Native HTML

The first rule to create a truly accessible form is to use native HTML form controls. They are accessible by default with all assistive technologies and it is semantically correct.

Let’s look at some examples of native form elements:

<input type=”text”>

<input type=”radio”>

<input type=”checkbox”>

<button>Submit</button>

Since we use the native HTML controls, the name, role, and state of the elements are exposed by default to all assistive technologies. But if we are creating a custom control using WAI-ARIA techniques, all of these elements need to be provided manually using various ARIA attributes like aria-label, aria-checked, role= “radio” etc.

Provide a Visible Label

Now that we have talked about using the native HTML controls for the forms, let’s dive into methods to make them accessible. The next step in the process is to provide visible labels for each form control. Without visible labels, form controls are not usable to any user let alone a person with a disability. A visible label is simply text that is in proximity to the form control that it is representing.

<b>First Name</b>

<input type=”text”>

<b>Terms & Conditions</b>

<input type=”checkbox”>

In the example code above, I have used a bold tag to highlight the labels so that users can distinguish them easily. While we are talking about visible labels, let’s recall a bit about placeholder attribute.

For some input types, we can use the placeholder attribute– but it is not the same as providing a visible label. The placeholder disappears once user inputs data into the form. To read more on the pitfalls of the placeholder, learn more in our previous article on the problem of placeholders.

Include Programmatic Labels

Now that we have understood why we need visible labels and, we also need to associate them programmatically to their form controls. Without the programmatic association of the labels, assistive technology users cannot identify the purpose of the form field.

When a user’s focus moves into a text field it is read out as “edit field” without notifying the accessible name provided to it. To make sure that the visible accessible name is notified to the users we need to associate the visible label with a form field.

<label for=”firstname”>First Name</label>

<input type=”text” id=”firstname”>

<label for=”lastname”>Last Name</label>

<input type=”text” id=”lastname”>

In the above example, we have used the id method to associate the form field with its visible label. While there are multiple ways to achieve the association using the id method is recommended.

Provide Descriptive Labels

Now that we have provided visible labels and associated them with their respective form fields, the next step is to check if the form labels are descriptive enough. That is, will the user be able to read through the label and perform the successful action? For example:

<label>Name</label>

<input type=”text”>

<input type=”text”>

In the above example, we can see that for both form fields the visible label is “name” but it is not descriptive enough for the users to take necessary action. Each form field should contain its own visible label and it should be descriptive. We would improve the example above by providing visible labels for both form fields and specifying where the first name and last name should be entered.

<label for=”fname”>First Name</label>

<input type=”text” id=”fname”>

<label for=”lname”>Last Name</label>

<input type=”text” id=”lname”>

Group Form Controls

Sometimes, there will be a set of form controls that belong to a group and is provided with a group level visible label. The group level label conveys the necessary information to the users to take action. Let’s see this with an example:

<p>Do you have a passport</p>

<input type=”radio” id=”yes”>

<label for=”yes”>Yes</label>

<input type=”radio” id=”no”>

<label for=”no”>No</label>

In the above example, we can see that “do you have a passport” is the primary visible label for the set of radio buttons. But when assistive technology users navigate to these radio buttons, they miss the key information provided by the primary visible label because it doesn’t receive tab focus.

In addition, the elements “Yes” and “No,” when read-out by assistive technology, doesn’t make sense. To help with this problem in HTML, we use fieldset and; legend attributes to help us bind the group level form controls. These attributes will be announced to assistive technology users as expected. Now we will see the same example with fieldset and legend:

<fieldset>

<legend>Do you have a passport</legend>

<input type=”radio” id=”yes1”>

<label for=”yes1”>Yes</label>

<input type=radio” id=”no1”>

<label for=”no1”>No</label>

</fieldset>

In the example above, we can see that fieldset is binding the form controls inside a group and the legend attribute is used as the primary label that will be exposed when assistive technology user moves the focus to the first radio button either in tab or shift+tab navigation.

Provide Instructions

Some of the form fields need additional instructions to fill the data successfully. These instructions must be available to the users at all times like visible labels. We can bind the instruction to the form fields using an aria-describedby attribute.

<label for=”dob”>Date of Birth</label>

<input type=”text” aria-described=”dob1” id=”dob”>

<span id=”dob1”>Use DD/MM/YY</span>

In the above example, the instruction is provided below the form field and is bound using an aria-describedby to the text field. If the instruction is not bound to form fields, then assistive technology users who use the tab key might miss key information.

In Summary

In summary, following the best practices discussed above will create a form that is usable and accessible to all users. Native HTML is the key to creating this positive user experience. If you want to build a custom control because something is not available in HTML, we only then recommend using ARIA roles, states, and properties. In the final post of this series, I will discuss how to create custom controls and error identification.

Photo of Raghavendra Satish Peri

About Raghavendra Satish Peri

Raghavendra Satish Peri is a digital accessibility evangelist working at Deque Systems as Product Manager [Accessibility] breaking web accessibility & mobile accessibility challenges.

He authors an Accessibility Blog & is galvanizing the adoption of accessibility by inspiring the local tech community with meetups and mentorship. When away from his computer, Raghava can be found at local cafes & restaurants sampling cuisines, attending local meetups, listening to audio books or writing on his Personal Blog.
update selasa

Comments 4 responses

  1. Hi, A small correction in your post above.
    In the example code for aria-describedby, You seem to just have aria-described as the attribute on the tag
    Thanks for the detailed explanations.

  2. What are your thoughts on html5 validation. Does it provide an accessible experience?

  3. Hello Ray,
    I am a screen reader user & from what my sighted peers told me is that when we use a HTML5 elements & use the submission process the errors appear & focus moves to the element… but the errors will disappear once I move my focus out of the input field. This is a failure of WCAG According to SC 3.3.1 errors must be available in text & SC 2.2.1 Timing Adjustable states that users must be provided with enough time to process the information.

    This means the errors must be available to the users in text all the time. HTML5 validation fails this.

  4. Hey Raghavendra,

    Can you please update your code?

    1. use real double-quotes instead of L/R ones (won’t validate otherwise)
    2. add name attribute (same value for each) to the radio inputs so they behave as expected for keyboard users.

    Thanks!
    D.

Leave a Reply

Your email address will not be published. Required fields are marked *