HTML forms are generally comprised of a number of
<label>s along with a
submit <button> at the end. But every now and again a non-form element appears within a form. We will deal with that in this article.
A unique challenge that forms present to us as web developers is that blind users interact with computers very differently than sighted users. Sighted users navigate pages through sight. Lots of information is presented at once, and the user determines what information to focus on at a time. Hopefully, before going from one page to another, the user will have focused on, and taken in, all relavent information on the page.
Blind users, however, must consume a page in a very different manner. They don't navigate by sight. They navigate by way of special keys in their screen reader. (Ex: "h" takes you to the next
<h#> heading, "t" takes you to the next
Once a screen reader user lands in a form element, the screen reader changes behavior; it enters "forms mode." Now, instead of "t" taking you to the next
<table>, it enters a "T" in the
So, how does a blind user interact with a
<form> in "forms mode"? There are two primary ways of doing this. The main way is to go from
<input> via the Tab key. The other way is to use the Esc key to exit "forms mode" and continue to navigate the page in the usual way.
(It is my personal opinion that once a user has started filling out a form, why would a user exit "forms mode" just to go to the next
<input> when Tab would do the job? A user may have a reason, but I think it's probably safe to assume that the majority would just use Tab. Even if some done, we need to code for those who do.)
To recap: A screen reader in "forms mode" will read the following HTML elements:
<label>s (for enabled
<fieldset>s with at least one enabled
It is safe to assume that once a blind user hits the first form element, they will stay in "forms mode" until they get to the
Submit <button>. (If that assumption is incorrect, but we code for it anyway, we hit all scenarios.)
A problem arises in the situation where a form has some extra information or instructions that comes after the first
<input> that's not in one of the above elements. A blind user will just Tab right over it and miss it completely.
We will use the following form as an example:
Ideally, all instructions for a form should come before the form begins. However, sometimes that not practical or possible. (Most forms on the web are small and simple. But in a corporate environment, (esp. a government site) forms can be long and complex.)
There are a few ways to solve this problem:
<textarea readonly>. Each has its own pros and cons. We will consider them each here.
ARIA stands for Accessible Rich Internet Applications. Aria- is a set of attributes that can be used in HTML elements to increase the accessibility of the web page. Aria- is to be used where HTML currently lacks. There's a common saying amongst accessibility professionals that goes
The first rule of Aria is: Don't use Aria.. That means: if there's a way to do something with native HTML, do it that way.
For example, don't do this:
<span id="myLabel">Enter your username</span> <input id="username" aria-labelledby="myLabel">
When you could do this:
<label for="username">Enter your username</label> <input id="username">
The two Aria- attributes that we're concerned with here are
aria-labelledby can be used when an element doesn't have a native
<label>. An element may only have one
aria-describedby is used to add extra information to an element; more than a
aria-describedby uses a space-separated list of
id values. It's perfect for extra information aside from what's in the
<label>. For example:
<label for="username">Enter your username</label> <span id="usernameExplanation">This is the username you used to register.</span> <input id="username" aria-describedby="usernameExplanation">
It can even be used for adding error messages. (Note the space deliminited list of
id values in
<label for="username">Enter your username</label> <span id="usernameExplanation">This is the username you used to register.</span> <input id="username" aria-describedby="usernameExplanation usernameError"> <span id="usernameError">I'm sorry but that username isn't valid for some reason.</span>
It's clean and it's proper.
The main limitation with anything Aria- is support. Browsers and AT (assistive technologies) don't support all Aria- attributes in a consistent way. Support for
<input>s is pretty good, support for
aria-describedby on just about everything else is pretty bad or non-existant. At the very least, it's inconsistent.
Another way to present non-form information in a form is to make it focusable by using
<label for="password1">Enter a password</label> <input type="password1" id="password1"> <p tabindex="0">Passwords must have at least one uppercase letter, one lowercase character, one numeric digit, be at least 8 characters.</p> <p tabindex="0">Both passwords must match.</p> <label for="password2">Re-enter password</label> <input type="password2" id="password1">
In the above example, a user would tab to the first password field, hit Tab, and the first paragraph would be focused (and read by a screen reader), then the second paragraph, and then the second password field.
The best things about
tabindex="0" are that it's simple to implement and widely supported (i.e.: all major desktop browsers).
The biggest disadvantage of using
tabindex="0" is that it's a usability problem for keyboard users. When you tab to something, you expect that something to be interactive. But simply adding
tabindex="0" to a
<p> tag makes it focusable, but non-interactive. This can be confusing. I have seen it described (by a blind person) as "Horrible Ux".
Another disadvantage is for sighted-keyboard-only users. They have to tab through all this stuff they can see (all the time wondering if the thing they're focused on is interactive, and if so, how to interact with it) just to get to the actual interactive parts.
Sometimes when a developer is told "This one section will be missed by screen reader users in forms mode. Add
tabindex='0' to fix," they hear: and they put it in almost every HTML element.
Another disadvantage is that using the "Next" button while filling out a form in iOS will skip over non-form elements, even if it has
tabindex="0". (However, it's fair to mention that blind mobile users interact with their devices completely differently than they do with desktop devices. So it's an apples and oranges comparison.)
<summary> tags can be used when implemented properly. When supported,
<summary> tags are naturally focusable. A user would Tab to it, hit Enter and/or Space to expand, and use the down arrow key to read the contents.
It's native HTML5, and the contents can be hidden or expanded at will.
Not all browsers support
<summary>, so polyfills would have to be created for those that don't. (These polyfills are included in Web Experience Toolkit (WET).)
Worse yet, they're relatively new and not entirely supported, and they don't do well in user experience testing. Sometimes you use Enter and sometimes you use Space. It's inconsistent.
Overlays can be kind of like a pop-up. You see them a lot when you read an article someone posted on Facebook and after the article loads a box shows up asking to send every article on that site to your Inbox.
Examples can be seen on a Web Experience Toolkit (WET) demo page.
Overlays are good for extra help on a form field that doesn't need to be displayed all the time (and may never be displayed).
They do better in user experience testing than
<summary>s. Since they're pretty common, users generally know how to use them.
Unless you're using WET on your site, they're not native HTML, so they can be hard to properly implement. Some sites always position them a relative number of pixels from the top-left corner of the viewing area. This is a problem for mobile users because they may never be able to bring the close button into the viewing area, so they can't close the overlay.
Also, if not implemented properly, they can wreak havok with keyboard tabbing. You may be able to tab out of an overlay without it closing. Or, you may accidentally create a keyboard trap.
Some suggest if you have a lot of information, why not put it in a
<textarea readonly>? This would make it focusable and readable, but not updateable.
It's simple and it uses native well-supported HTML. You could even use CSS to make the borders disappear, or look any way you want. No polyfills are required.
It's a hack. It's Not's not semantically correct. A
<textarea> is for the user to enter or edit a large amount of data to be sumbitted as part of the form.
<textarea> has a
form attribute in it to point to a different form, then the contents of that
<textarea> will be sent to the server. It's not clean, it's not efficient, and it's not semantically correct (which is a WCAG 1.3.1 - Info and Relationships issue).
Which Should I Use?
Which solution should you use when you must have non-form information inside a form? While each situation is unique, here are some guidelines to help you decide.
- There is lots of extra information (several paragraphs).
- The extra information pertains to all fields, or a whole
- There is not a more appropriate native HTML or Aria- way of doing it. (ie: it wouldn't make semantic sense to make it a
- The extra information does not apply to any
<input>s, but to some other HTML tag.
- You have no other option.
- The extra information applies to one or two individual
<input>s, and not an entire form or form section.
- The extra information only applies to
- The amount of information is small, such as 2 or 3 sentences.
- The information can be hidden most of the time and only needs to be revealed occasionally. An example would be a section on "Help on filling out this form". In this case, it would come before the form even began, and a screen reader would not be in forms mode.
- It's the future and all major browsers natively implement them and they do better in user experience testing.
Use Overlays When:
- The information can be hidden most of the time and only needs to be revealed occasionally. An example would be a section on "Help on filling out this field" (usually denoted with a "?" icon).
- You're certain you're using an implementation that has been tested for usability and accessibility, such as the Web Experience Toolkit (WET)
Use A Readonly
- You're trying to make me angry.