Jump to main content

Accessible form validation

Often an asterisk (*) is used to indicate which fields are required in a form. Most of the time it can be good to follow conventions.
The asterisk work as a visual hint for the user, but what about visually impaired users? For them an asterisk doesn't give much info.

One way to solve this is to use the <abbr> tag to describe the asterisk.
Html 5 also has the required attribute which should be used on required fields.

<p>Required fields are marked with an asterisk <abbr title="Required field">*</abbr></p>
<form method="post" action="/">
	<label for="email">E-mail <abbr title="required">*</abbr></label>
	<input type="email" name="email" id="email" required />
</form>

In addition to just highlighting which fields are required, it's important to give a good validation feedback.
This can be done by having a general form message with a summary of the errors. Then it's also good to write an error description per field.

Here we're using role="alert" which will announce the text for assistive technologies. We don't need to use aria-live="assertive" because role="alert" have an implicit aria-live value of assertive. It is important that the tag with role="alert" is present in the html from start and that the content in it is dynamically changed. If you dynamically create the role="alert" tag it won't be read by assistive technologies.
For the per field error message we're using a div which is connected to the field via the aria-describedby attribute.
aria-atomic="true" makes sure the screen reader present the live region as a whole and not only the part of the region that changes.

<p>Required fields are marked with an asterisk <abbr title="Required field">*</abbr></p>
<!-- We're using novalidate attribute here to avoid the built in browser validation -->
<form method="post" action="/" id="test-form" novalidate>
	<div id="form-message" role="alert" aria-atomic="true">
		<p>Please review the form and fix the following errors:</p>
		<ul>
			<li>The name field must be filled in.</li>
			<li>The e-mail field must be filled in.</li>
		</ul>
	</div>
	<div class="form-field">
		<label for="name">Name <abbr title="required">*</abbr></label>
		<input type="name" name="name" id="name" required aria-describedby="nameDesc" />
		<div id="nameDesc">The name field must be filled in.</div>
	<div class="form-field">
		<label for="email">E-mail <abbr title="required">*</abbr></label>
		<input type="email" name="email" id="email" required aria-describedby="emailDesc" />
		<div id="emailDesc">The e-mail field must be filled in.</div>
	</div>
	<button type="submit">Send</button>
</form>

Here is a Codepen that demonstrates the form validation:

https://codepen.io/overtune/pen/KKpWjjQ

Additional tips

Read more / sources: