Accessible Client-side Form Validation with HTML5

By Paul J. Adam May 03, 2012
View non-AMP version at deque.com

Connecting labels to inputs is easy! But what about required fields, error messages, and keyboard focus?

In this three part blog series we’ll learn to make accessible forms with HTML5, WAI-ARIA, and jQuery Validation. Our strategy will be to first try validation with HTML5 in the latest browsers that support these form attributes, then we will use WAI-ARIA which works with the latest screen readers, and finally for the folks who just can’t upgrade we’ll add the jQuery Validation plugin so even IE6 users can accessibly submit forms.

Basics

The basics of form accessibility are sometimes overlooked so I’ll point them out for review.

Every. Single. Field. Needs. A. Label.

Easy enough to remember? The only bulletproof way to ensure an accessible form field is to provide an explicitly connected label using the for and id attributes.

A quick test for an explicit label is to click on the label’s text with your mouse and if focus goes into the input then they are connected. This increases the click target size and really helps everyone click those tiny checkboxes and radio buttons.

Technique for WCAG 2.0 – Success Criteria 1.1.1 (Non-text Content), 1.3.1 (Info and Relationships), 3.3.2 (Labels or Instructions), and 4.1.2 (Name, Role, Value)

H44: Using label elements to associate text labels with form controls

HTML

<label for="fname">First Name *</label>

<input required type="text" name="fname" id="fname">

Output

Do this for every single field! If you don’t want to see the label then hide it off screen with CSS.

Radio Buttons & Checkboxes Need a Fieldset & Legend

HTML

<fieldset>

<legend>Gender *</legend>

  <input type="radio" name="gender" value="male" id="male">

  <label for="male">Male</label>

  <input type="radio" name="gender" value="female" id="female">

  <label for="female">Female</label>

</fieldset>

Output

Gender *

Technique for WCAG 2.0 – Success Criteria 1.3.1 (Info and Relationships) and 3.3.2 (Labels or Instructions)

H71: Providing a description for groups of form controls using fieldset and legend elements

Are All Instructions Spoken?

Are input formats spoken? Did you indicate the correct format for dates, phone numbers, etc.? Again, the best way to communicate form instructions to screen readers is to place them in the label.

HTML

<label for="bday">Birthday * MM/DD/YYYY</label>

<input type="text" name="bday" id="bday">

Output

Technique for WCAG 2.0 – Success Criteria 3.3.2 (Labels or Instructions) and 3.3.5 (Help)

G89: Providing expected data format and example

Required Fields

No one enjoys filling out forms! If you want to get useful data and not scare your users away then only require the least amount of fields as is necessary. Indicate the field is required by placing a red * in the label or the text (required).

Technique for WCAG 2.0 – Success Criterion 3.3.2 (Labels or Instructions)

H90: Indicating required form controls using label or legend

Error Messages

 

Help users out by providing useful error messages and suggestions to correct them. Placing the error in a label will cause a screen reader to speak each error as the user tabs through the form fields.

Keyboard Focus

One of the biggest failures with forms is not sending keyboard focus to the field with an error or the list of error messages. Assistive Technology users will have no idea there’s something wrong if the screen reader goes blank or their magnifier does not move focus to the error. When nothing happens after pressing the submit button they will assume your form is broken.

Techniques for WCAG 2.0 – Success Criteria 3.3.1 (Error Identification), 3.3.2 (Labels or Instructions), 3.3.3 (Error Suggestion), and 3.3.4 (Error Prevention (Legal, Financial, Data))

HTML5

Now that you’ve got the basics out of the way, adding HTML5 validation and usability enhancements is a piece of cake!

Required Attribute

With the HTML5 required attribute and HTML5 input types you can put the responsibility of accessible form validation on the browser developer.

HTML

<label for="lname">Last Name *</label>

<input type="text" name="lname" id="lname" required>



<input type="checkbox" name="tos" id="tos" required>

<label for="tos">* I agree to terms of service.</label>

Of course the required attribute does not work on all browsers, Safari and Mobile Safari being the two where I miss support the most. You can read more about HTML5 browser support at The Current State of HTML5 Forms – The required Attribute by Chris Coyier (@chriscoyier) of CSS-Tricks fame. That resource is a bit out of date as support has improved in many browsers.

Input Types

 

HTML5 input types greatly enhance the usability and accessibility of forms on mobile devices. In iOS, the iPhone, iPad, & iPod Touch platform, most input types will display a keyboard enhanced for that data format. It is very rare to see forms in the wild take advantage of these simple usability enhancements. By default input type=text displays the normal alphabetic keyboard. If you need to type numbers, the @ symbol in an email address, or the .com for a URL extra taps are required.

Comparison of Input Types and Displayed Keyboard on the iPhone
Type type=text type=email type=tel
HTML
<label for="text">Text:</label>

<input type="text" name="text"

 id="text">
<label for="email">Email:</label>

<input type="email" name="email"

 id="email" />
<label for="tel">Tel:</label>

<input type="tel" name="tel"

 id="tel" />
Output

input type=date on iPad & iPhone

HTML
<label for="date">Date:</label>

<input type="date" name="date" id="date" />
Output

 

Because these different keyboards and spinner controls are native to iOS they’re accessible by default. Apple’s done all the work for you.

Pattern Attribute

HTML
<label for="zip">Zip Code 5 Digits</label>

<input type="number" pattern="[0-9]*" maxlength="5" min="0" name="zip" id="zip">
 Output

Using the pattern attribute, pattern=”[0-9]*”, with the number input type will display the 10-digit numeric keypad similar to the tel keypad. This is much more usable than the standard number keyboard which shows a lot of keys that are not needed for simple numeric input like a Zip Code. We have fat fingers and mobile keyboards have tiny buttons. Anything you can do to increase the tap target size of a button really helps out!

HTML5Pattern.com has Regular Expression patterns that can be used to validate complex input types. These are live and can be tested in supported browsers.

You can visit HTML5 inputs and attribute support in a browser to test its support for HTML5 forms and click through all the input types. Another great page to test support for HTML5 form attributes is the jQuery Mobile – Text inputs Docs. I love the jQuery Mobile project as it does two things I’m passionate about, mobile & accessibility, very well!

Input Types Add More Stringent Validation

By adding an input type=email the browser will ask for more specific input formatting to make sure the user actually types an email address in the format name@domain.com.

 

If we add the required attribute to input type=number Firefox will ask for numeric data that matches the specified pattern attribute.

 

Simple Mobile & Screen Magnification Usability & Accessibility Enhancements

Place Label Above Input

By placing the label directly above the input you improve the experience for mobile and screen magnification users. When focus is in the input the label will no longer be cut off like in the below example of the Gmail sign up form where the label is placed to the left but cut off when viewed on an iPhone.

 

Position Formatting Instructions Below Input with CSS

Using CSS you can enclose formatting instructions in a span tag and position them directly under the input so they are still visible when zoomed in.

HTML

<p class="instructions-container">

  <label for="zip">Zip Code <span class="instructions">5 Digits</span></label>

  <input type="number" pattern="[0-9]*" maxlength="5" min="0" name="zip" id="zip">

</p>

CSS

.instructions {

    position:relative;

    top: 1.6em;

    display:block;

}

.instructions-container {

    margin-bottom:2em;

}

.instructions-container label {

    margin-bottom:-1.2em;

}

Hiding Labels Using CSS

You may want to visually hide some labels where the input might be obvious to most sighted users. We can use CSS positioning to do this. The code for this comes from the WebAIM article, CSS in Action: Invisible Content Just for Screen Reader Users.

HTML

<label for="areacode">Phone * <span class="hidden">Area Code</span></label>

<input required type="tel" name="areacode" id="areacode" maxlength="3">

-

<label for="threedigits" class="inline"> <span class="hidden">First Three Phone Digits</span> *</label>

<input required type="tel" name="threedigits" id="threedigits" maxlength="3">

-

<label for="fourdigits" class="inline"> <span class="hidden">Last Four Phone Digits</span> *</label>

<input required type="tel" name="fourdigits" id="fourdigits" maxlength="4">

CSS

.hidden

{position:absolute;

left:-10000px;

top:auto;

width:1px;

height:1px;

overflow:hidden;}

You can disable CSS and the labels will become visible.

Next Steps – Add WAI-ARIA

In the next blog post we’ll build off the work we did here and add ARIA form and validation enhancements that are only visible to screen readers.

Links to all three posts in this series:

  1. Accessible Client-side Form Validation with HTML5
  2. Accessible Client-side Form Validation with HTML5 & WAI-ARIA
  3. Accessible Client-side Form Validation with HTML5, WAI-ARIA, & the jQuery Validation Plugin

Comments? Questions?

So what do you think about HTML5 form validation? Is this a viable option with the limited browser support of the required attribute? Do we still have to rely on JavaScript validation or even server-side validation since a small percent of users disable JavaScript?

Let me know if you have any suggestions for improvement or find any mistakes.