Inclusive web development: web form accessibility guide

Chris de Groot
Pon.Tech.Talk
Published in
9 min readAug 23, 2024
Photo by Artem Sapegin on Unsplash

In today’s digital age, the internet is one of the most used sources for information and communication. Yet, for many individuals (with or without disabilities), navigating the web can be a daunting experience due to poorly designed websites and inaccessible content. One of the biggest issues involves HTML forms, which are necessary for processes like logging in, signing up, and making purchases online. Without forms, a lot of webshops and social media sites would be unusable.

Accessible HTML forms ensure that all users, regardless of their physical or cognitive abilities, can interact with it in an effective way. This article will cover the best methods for creating forms that are not only functional but also inclusive. From structuring your forms with semantic HTML to employing ARIA (Accessible Rich Internet Applications) roles and properties, I will provide you with practical tips to enhance the usability of your web forms.

Together, we can make the web a more inclusive space for everyone.

Use semantic markup

A form should always start with a <form> tag. This is essential because some screen readers only activate form-specific functions when they detect the <form> tag. However, some developers wrap input fields in a regular <div> and use additional scripts to handle form functionality, which can lead to accessibility issues.

There is also a user experience benefit to using the <form> tag. For example, when you fill out a form and press the “Enter” key, the form often submits automatically, even without clicking a submit button. This is a built-in feature of browsers when the <form> tag is used.

It’s crucial to use appropriate HTML input types. Native form elements offer essential functionalities that are difficult to replicate, such as keyboard navigation, focus management, client-side validation, and accessibility features supported by screen readers. There is a wide range of types you can use, such as <input>, <select>, and <textarea>. Choosing the right type depends on the specific input requirements. Styling wise there are a lot more options available with default HTML elements than a few years back so there is no reason to resort to implementing custom elements.

Additionally, when dealing with related inputs (like first name and last name), encapsulate them in a <fieldset> element with a <legend> to provide semantic grouping, especially useful for radio buttons or checkboxes:

<fieldset>
<legend>Select your pizza toppings:</legend>
<input id="ham" type="checkbox" name="toppings" value="ham">
<label for="ham">Ham</label><br>
<input id="pepperoni" type="checkbox" name="toppings" value="pepperoni">
<label for=”pepperoni”>Pepperoni</label><br>
<input id="mushrooms" type="checkbox" name="toppings" value="mushrooms">
<label for=”mushrooms”>Mushrooms</label><br>
<input id="olives" type="checkbox" name="toppings" value="olives">
<label for="olives">Olives</label>
</fieldset>

Note, screen readers may repeat the legend for each control in the group, so the legend text should be brief and descriptive.

Pay attention to the name attribute of the HTML input field, some inputs (specifically the radio type) do not behave as expected. If you omit the name attribute, every radio input is treated as a separate input, rather than as different options in a group making it difficult to navigate through the options with a keyboard.

Code example — Missing `name` attribute

This example is invalid, since the name attribute is missing. Therefore each radio button is treated as an independent option. This allows multiple radio buttons to be selected simultaneously, which is not the intended behavior.

Code example — Valid `name` attribute

This example is valid, as all the radio buttons share the same name attribute (name="options"). This groups the radio buttons together, ensuring that only one option can be selected at a time.

Use of labels

TL;DR: Every form input needs a label, even though it’s often omitted for aesthetic reasons to keep the design clean. Labels are important because clicking on them will automatically focus the related input field without any additional code. There are two ways to label a field: using explicit labels and implicit labels. If you prefer not to display a visible label, you can use the aria-label attribute to provide an accessible label for screen readers, ensuring the input is still properly labeled for accessibility purposes, but this comes with its own trade-offs which will be discussed later.​​

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

This structure is called an explicit label. Matching values for the HTML attributes for (on the label) and id (on the field) values associate the label with its form field. As id attribute values must be unique on each page, a field can only have one associated `<label>`.

You can also create the association by placing the label text and the input within the <label> element (and not using for and id), this is called an implicit label.

<label>Name: <input type="text" autocomplete="name" placeholder="name"></label>

However, the implicit method has a downside: some assistive tools (such as Dragon NaturallySpeaking) do not support it. Therefore it is mandatory to always use an explicit label.

When you really can’t convince your designer to design a form without visual labels, there is a third method of designing accessible fields. You can use the aria-label attribute, which is very useful for adding contextual labels for elements without adding visual labels. This is great for accessible inputs (for screen-readers) with no visible labels (or labels that look like placeholders):

<input name="name" aria-label="Name" placeholder="name">

Please keep the following in mind as there are some potential issues for users that rely on client-side translation. For example, some users might visit your website in your language, while they may speak a different language. Let’s say they have a browser extension that translates page content into their own language. If they do so, the value of your aria-label attributes may not be included in the translation.

Worth mentioning is that the implementation of the aria-* properties might differ from browser to browser and from device to device. More information is available through the following article on the website of the Accessibility Developer Guide: https://www.accessibility-developer-guide.com/knowledge/aria/purpose/#non-homogenous-behaviour

Autocomplete suggestions

Most websites use forms to request the same information from users: email, address, phone, credit cards, etc. And a very nice feature that is built into the browsers is the ability for users to save their own information so that it can be auto-completed across different forms and sites. The autocomplete attribute enables us to leverage this browser feature. As your users will benefit greatly from this, there is no reason not to include it in your code.

The autocomplete attribute is valid on any text or numeric HTML inputs. The most used autocomplete options are for example tel for a phone number, `​​email` for an email address and given-name and family-name for first- and last names. A complete list is available on https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete

Inputmode

inputmode is an HTML input attribute that lets you tell the browser the input format. On a desktop computer you won’t notice it, but for mobile users it makes a huge difference. By selecting different input modes, the browser will present the user with a different virtual keyboard to input their data.

You can greatly improve the user experience of filling out a form for mobile users by simply adding a different input mode. For example, if you are asking for numeric data like a credit card number, you can set the inputmode to numeric. That makes it easier for the user to add numbers. For an input asking for an email address, you can use inputmode=email. Just as with autocomplete, this is a feature you should include in your forms.

Some examples, with screenshots, can be found at https://www.geeksforgeeks.org/html-inputmode-attribute/

Error handling

A common way forms indicate invalid fields is to change the <input> border color to red which is not ideal. The reason for this is because a change in color alone is not exposed to assistive technologies, so indicating errors in such ways will not inform the person of the error. Also, relying on color alone may also not work for someone who is red/green colorblind. In addition to the above, implementing this correctly could also increase the number of successful submissions, as is demonstrated in the following article: https://alistapart.com/article/inline-validation-in-web-forms/

Each field with an error should have a clearly visible, programmatically linked inline error message directly below it. The aria-describedby attribute is a method for associating these error messages with their respective fields.

<label for="name">Name (required)</label>
<input type="text" id="name" aria-describedby="error">
<span id="error">Name is required. Please enter your response.</span>

Note: Avoid using the ARIA role="alert" for error messages referenced by aria-describedby. Some assistive technologies may not convey the description if it has an alert role. You can also use aria-live="polite" instead of role="alert". This attribute creates a live region for updates, which is especially useful for notifications that appear before the form is submitted.

When multiple fields have errors, provide both inline error messages and a summary list at the top of the form. This list should include links to the specific fields.

Error messages should be straightforward and specific, clearly explaining what went wrong. Whenever possible, offer guidance on how to correct the mistake. For single errors, direct the focus to the invalid input field immediately so users can correct it immediately. For multiple errors, shift the focus to the error summary at the top of the form. This approach informs users about the number of errors and their locations, making it easier to navigate and fix them.

More information is available via https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation#validating_forms_using_javascript and https://www.w3.org/WAI/tutorials/forms/notifications/#firstname

Focus state

Today, every modern web browser has a different default visual styling that applies to focusable elements on your website or app — some more easily visible than others. When a user presses the tab key on their keyboard to “tab” through the page, this styling is applied as the element receives keyboard focus.

A focus indicator shape can take on many forms, be it an outline, a border, an underline, a box, a background change, or some other style that does not rely on color alone to indicate the keyboard’s focus is active on that element.

There is no rule about how many focus indicator styles you have on one page — but be sure to keep it to a reasonable number to avoid unnecessary confusion. Ideally, things that look the same will do the same, and by limiting the number of different styles for the same elements across your website will yield less unexpected situations for your users and a better overall experience. The only rule here is, the design should adhere to the 3:1 color contrast ratio as set by WCAG and that it should be easily identifiable by your users (see https://www.w3.org/TR/WCAG20-TECHS/G145.html).

Pagination

Filling out long forms can be overwhelming, especially for individuals with ADHD but not limited to. This often results in people stopping halfway or not even starting filling in the form, which is far from ideal. One effective way to solve this issue is to divide the form into smaller, more manageable sections. This approach makes the form less intimidating and easier to navigate.

Here are some key principles for designing multi-step forms:

  • Ensure that users are reminded of the form’s purpose and instructions at each step.
  • Break the form into logical sections to make the content more digestible.
  • Keep users informed about their progress through the form, which can motivate them to complete it.

Note: There are no strict rules defining how long a long form is. However, it’s important to assess whether the form can be logically divided into smaller sections to improve user experience.

Forms are often subject to the “Goldilocks principle” [https://en.wikipedia.org/wiki/Goldilocks_principle]. The Goldilocks principle dictates that when you use forms that are too long, they discourage users from completing them. Too short and you end up with leads that are less relevant.

When you require more information, multi-step forms strike a better balance because you can leverage more form fields to collect all the information without scaring off visitors and therefore increasing your conversion.

Closing thoughts

Choosing the right input types improves the experience on many levels: semantics, accessibility, and user experience. Website visitors are used to the way input fields work across the web, so we can take advantage of that by using the same inputs for the same things. Not to mention that by using the right inputs, we get a lot of things for free like keyboard navigation support and validation. By sticking to simple designs that use standard input types and by leveraging all the form options a browser comes with out of the box, you can create a more cohesive and inclusive experience, not only across your site, but across the internet. I hope that by reading this article you will have a better understanding of how to make your website forms more inclusive.

Sources:

https://www.a11yproject.com/posts/how-to-write-accessible-forms/
https://webaim.org/techniques/forms/controls
https://web.dev/learn/accessibility/forms
https://accessibility.huit.harvard.edu/developers
https://austingil.com/how-to-build-html-forms-right-semantics/
https://www.w3.org

--

--