Accessible Form Instructions
Making web forms accessible for people who use screen readers can be a bigger challenge that it seems. The basics are straightforward -- associate a label with each field, add fieldsets and legends when necessary, make sure the tab order makes sense -- but these techniques may not be enough. Consider the following example:
Create a password that is at least 8 characters long and includes both letters and numbers.
Seems simple -- labels are associated; no fieldset is needed; tab order is correct. The problem is with the instruction between the User Name and Password fields: it is a simple HTML paragraph, but most screen reader users will never hear it.
The Problem
Screen readers use a special mode to read web pages (called "Virtual Cursor" in JAWS and "Browse Mode" in Window-Eyes). In this mode, all the text on the page can be read, and special commands are available to skip from heading to heading, navigate within tables, etc. However, there is one big limitation -- while in this "virtual mode", screen readers cannot enter data into text inputs, text areas, or select controls.
To enter data, screen readers must switch into "forms mode". With forms mode active, the screen reader relies on the browser's page navigation commands -- tab and shift+tab -- to move through the page. Because these commands work only with focusable elements -- links, form controls, and elements with tabindex -- only these elements, and their associated labels, titles, and legends, can be read. In the example above, the instruction is not focusable, and therefore cannot be read while in forms mode.
Solutions
While the best solution may be to avoid the problem altogether by using good design to minimize the need for instructions, the following examples demonstrate several techniques that can be used to make instructions readable:
Method 1: Hidden Instruction Repeated in Label
The text of the instruction is repeated in the label and hidden to sighted users by using CSS to position it off the screen:
<label for="field2">Field 2: <span style="position: absolute; left: -10000px;">Instruction for Field 2.</span></label>
Instruction for Field 2.
This method is effective, but requires that the instruction be maintained in two locations. Because the instruction must be nested within the label, it cannot contain multiple paragraphs, lists, or other block-level elements.
Method 2: Focusable Instruction
The instruction is made focusable by wrapping it in a link element without a href attribute; tabindex is set to zero to keep it in the tab order:
<p><a tabindex="0">Instruction for Field 2.</a></p>
This method is effective for screen reader users and only requires the instruction to be entered/maintained once. It can be used for instructions that include multiple paragraphs, lists, etc., although each block-level element must contain its own link. The main drawback is that the instructions will be additional tab stops for anyone who uses the keyboard to navigate the form.
Note: using tabindex without the link element (e.g., by setting tabindex directly on the paragraph element) does not work with the latest versions of JAWS (7.10 through 9.0); JAWS reads the wrong text in an apparent attempt to find and read a label for the element.
Method 3: Multiple Labels
The instruction is wrapped in a label element associated with the field in addition to its regular label:
<p><label for="field2">Instruction for Field 2.</label></p>
This method only works with JAWS 9.0.2152 (April 2008) or newer (and not with Window-Eyes as of version 6.1). The instruction text only needs to be entered/maintained once, and it does not add tab stops for non-screen reader users. Multiple labels can be used for instructions that contain multiple paragraphs, list items, etc., by wrapping the content of each block-level element in its own label.
More Information
To see all the cases tested in determining the methods identified above, see our Form Instructions Test.
If you have questions or suggestions, please email accessibility@msfw.com.
