Making an Accessible Form with ARIA, Part 2

Share on FacebookShare on LinkedInShare on Twitter

When Things Can Change: Making dynamic content accessible

This is my third blog on using ARIA. The previous posts are:

How to use ARIA: An Introduction

Making an Accessible Form with ARIA, Part 1

In this blog we are going to use ARIA to make an accessible form with validation checking; however, you can also use this as an example of how to use ARIA to make any dynamic content accessible.

Look at the following form:

Example of a basic search form.

 

 

 

 

 

If you were to hit submit without anything in the text box, you would get an error message:

The same basic search form with an error message that reads, "You need to enter a search term before pressing submit."

 

 

 

 

However, people who are using assistive technology (AT), like a screen reader, will often not know that there is an error message. How would they?  Their screen reader is still at the go button. How are they to know that the message popped up below the form?

Unless... the author used ARIA. ARIA lets assistive technology (AT) know what things are (the role), what they are doing (the state), and what changes.  So ARIA is really useful for changing dynamic content.

In the first blog on aria, I said the there were 5 steps to making complex things accessible with ARIA. Let's take a quick look at them again.

Lisa's 5 ARIA steps:

1.  Alert users to what each element is: Their role (such as checkbox).

2.  Alert users to their properties and important relationships (such as "disabled", "required", and other labels).

3.  Alert users to what each element is doing: The state (such as checked).

4.  Alert users to changes in their state.

5.  Make sure widgets are keyboard accessible and focus works predictably. Events can be triggered though the keyboard, and it should be intuitive to the user. All controls should receive focus via tabbing though the keyboard.

The first step is to look at the roles. Just as a quick reminder: roles tell us what a thing is - what behaviors we can expect from it. Roles are what things are.  In contrast a state is what they are doing. For example, let's say I am a person; it doesn't matter if I am brushing my teeth or singing a song, I am still a person. It didn't change just because I changed what I am doing. That would mean I could have a role of person. The same is true for a checkbox, menu bar, and any other widget. It does not change when I check a checkbox, uncheck it, or if even if it is disabled. It is still a checkbox.  That doesn't change.  That is its role. Roles set expectations of how an element or group of elements will be used.

Step 1:  Set roles

Rule of thumb: elements that change how they look based on user interaction often need a role. Look at the element tag name. Does it change in a way that you would expect that element to change?

Our form uses HTML standard form controls so we do not need form control roles as well. But does anything else need a role?Look at the error message in the screen shots above. It is tagged as a header, but is that really all it is?  Headers typically belong in a table of content. A header is an element that provides structure, summarizing a section of content.

Our error message doesn't really do that. In fact, its role is very different. It alerts the user to a problem with content above. That is a big part of our accessibility problem: our header does not act like a header. It changes based on the user interaction, it toggles between visible and invisible. Functionally, it acts more like an alert box then a header.

As it acts more like an alert we are going to use ARIA roles to let the assistive technology (the user system) know what it should expect from it.

The Alert Role

Use the alert role on important messages to the user that requires the user's immediate attention. When this role is added to an element, the browser will send out an accessible alert event to assistive technology products that can then notify the user about it.

Example:

<h2 role="alert">Your form has not been submitted  because of  missing information.</h2>

Note: The element that the alert role is used on does not have to be able to receive focus, as screen readers will automatically announce the alert regardless of where keyboard focus is currently located (similar to  aria-live="assertive"). Also note that if an alert also has controls (such as an "OK" button ) the alert dialog role should be used instead.

Step 2: Set properties and important relationships

In Making an Accessible Form with ARIA Part 1 we  showed how to use aria-required and aria-described by, which are useful properties that would stop the user from making a mistake in the first place.

Here is how I used these elements in our form.

<input aria-describedby= "divinstruction"  aria-required="true" type="text" name="text1" id ="text1"/>

...

<div id="divinstruction">

  <p>This search is for the mysite.com (not the web)</p>

  </div>

Again, ARIA is all about telling the user what things are, what their properties are, and what they are doing. The more we manage and include this information, the more accessible our content is.

Step 3: Set the states.

States are things that change. Roles are what the thing is, but states are what the thing is doing NOW.   Roles don't change, states do.

Let's return to my earlier metaphor: I am a person. Person is what I am, so it would be my role.  It doesn't matter if I am brushing my teeth or singing a song. I am still a person. It didn't change just because I changed what I was doing.  However, brushing my teeth or singing are actions I perform or things I do, so those would be states.

Roles can support states.  A thing with a role person could support states like brushing teeth or singing a song or blogging.  Supported states are the kind of things you expect something with that role to do.

So I, with role person, can blog.  Blogging is a supported state for the role person.  My pet dog, on the other hand, cannot blog. He does not have role person but role dog.  And role dog does not support state blogging.

Got it? Great. Back to our form.

When you have a role, think about what the states are - anything that changes. Well, with our error message - our alert - what changes is whether you can see it or not. Sometimes it is hidden, and sometimes you can see it.

Aria-hidden

Aria-hidden is a state that indicates that the element and all of its descendants are not visible or perceivable to any user. Assistive technologies will skip hidden elements.

If an element becomes visible after some user action, authors MUST set the aria-hidden attribute to true in the Javascript.

Example:

<div id="e1" aria-hidden="true" role = "alert"> You need to enter a search term before pressing submit</div>

FYI: You can (if you want) use a CSS rule to show or hide the element based on the value of the aria-hidden state, for example:

div[aria-hidden="true"] {display:none;}

div[aria-hidden="false"] {display:block;}

You can also use the HTML 5 hidden attribute:  <p hidden >This error message will pop up if you make an error.</p>.

You can use CSS display:none for browsers that do not yet support hidden

.hidden {display:none}

 

Step 4 - Changing state:

There is no point at all in setting states if you do not remember to change them when their values change. Whenever you are using a script to change a presentation of something, you are probably changing its states. Just toggle the state at the same time.

If the content is incorrect, JavaScript function will toggle value of aria-hidden in the alert and aria-valid on the text box.

Example:

if (invalid) {

....

document.getElementById('').setAttribute('aria-hidden', 'false');

}

 

Note you were writing the code if (invalid) {} anyway. You had to - that is when you changed the way it looked. All we did here is add one line of code to change the state at the same time.

You can also set aria invalid because we now know that the value of the text box is invalid. So now we have:

if (invalid) {

....

document.getElementById('').setAttribute('aria-hidden', 'false');

document.getElementById('text1').setAttribute('aria-invalid', 'true');

   }

A word on aria-invalid

Aria-invalid is used to indicate the field is either correct or incorrect.  If the value is computed to be invalid or out-of-range, the application author should set this attribute to true.

Values for aria-invalid include:

  • aria-invalid="grammar" - A grammatical error was detected.
  • aria-invalid="true" - The value entered by the user has failed validation.
  • aria-invalid="false" - No error was detected. (Default.)
  • aria-invalid="spelling" - A spelling error was detected.

Step 5 - focus and keyboard:

Initially the alert box is hidden and out of the tabbing order; however, as the alert is automatically read to the user and no response is required, there is no need to set focus.All the other controls are standard HTML controls and so the focus and keyboard accessibility has been taken care of.

That is it.  We told AT (assistive technologies) what things are, what they are doing, their properties, when they changed, and we managed the focus.  The same five steps will make pretty much any dynamic content accessible.

[hs_action id="8223"]

 

3 comments

  • Raghava Permalink

    Hello ,

    Amazing article that taught me a lot about making forms accessible, how do we go around making long forms accessible. Am interested to know how do we throw errors in a intuitive way so that users are not lost while filling long forms.

  • ARIA Landmark Roles and Page Structure Permalink

    […] This post is part of my blog series on using ARIA. This post talks about using ARIA landmark roles. You do not have to have read the previous parts to understand it, but if you want to, here they are: How to use ARIA: An Introduction,  Making an Accessible Form with ARIA, Part 1, and Making an Accessible Form with ARIA, Part 2. […]

Leave a Reply

You can use these HTML tags:

<a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>