Return to ARIA Examples Index, or the ARIA Accessibility Home Page

ARIA Form Example


Notes: This form is a test for ARIA properties. We want the error text to be read as soon as the form is submitted with empty text and we want the instructions below to be read with the label of the search form. The form itself does nothing.

This search is for the (not the web)


Although the code is short and simple, it is fully accessible. This example uses:
  1. aria-describedby to make all instructions and relevant information read with the form field.
  2. aria-required is also used on the form field
  3. The error message uses the alert role that makes sure the focus is properly managed
  4. When an error is found the following states are toggled: aria-invalid in the form element and aria-hidden on the error message.
  5. CSS selectors are used to bind aria-hidden and CSS display:none.



Step by Step: How we made the tab panel (tutorial)

In the discussion on ARIA, we discussed 5 steps to making complex things accessible with ARIA.

  1. Alert users to what each elements 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.

Step 1: Set roles.

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 what a section of content is.  

Our error message does not 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 so we are going to use ARIA role alert to let the assistive technology (the user system) know what it should expect from it.

Rule of thumb - Elements that change how they look based on user interaction often need a role. Check the element tag name to check that any changes are expected that element. If they are not expected, you probably need a role.

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

Step 2: Set properties and important relationships

We want to make sure the structure, relationships between elements and groups, properties and labels are all clear in the code. They can be clear from the structure of the HTML code (or DOM), or using ARIA.

Our form has instructions and context information below the form that a screen reader user would not get to before they submit the form. This is a classic accessibility problem with forms. The relationship between the instructions and the form control is not clear from the DOM. We use aria-describedby to solve this type of problem.

Another really useful aria state for forms is aria-required. Aria-required indicates if a form field is required. Putting them together we have

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

<div id="divinstruction">
<p>This search is for the (not the web)</p>

Note that it is always worth looking at any requirements such as required states, and supported states for your roles before deciding what properties and states you need.

Step 3: Set the initial states

A good rule of thumb is elements that change how they look often have states that can change. The error message change from being non-visible to visible. So we are going to use aria-hidden as our states.

We also use CSS selectors, to change the look of the tabs and show and hide the panels based on the aria-hidden value. Now I do not need to change their CSS class in the code, only the value of aria-hidden or aria-selected.

In the CSS:

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

and the updated HTML:

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

We set aria-hidden='false'in the HTML, and set aria-hidden='true'in the document ready function so that it is hidden as soon as the document load. This way the alert roles works better with older screen readers then setting setting aria-hidden='true' in the initial HTML..

Step 4: Set changes in state.

We discussed above that we are using the aria states of aria-hidden and aria-selected, and we are using CSS selectors so that whenever aria-hidden='true' the panels will be hidden and when aria-hidden='false' the message will be visible.

In the code we have a function to change the values of aria-hidden when the code is validated. We can also set aria-invalid="true" so that screen reader users will know where the problem is.


A word about backward compatibility....

Unfortunately IE 9 does not support the CSS selectors above. (IE 10 does support them.) So to make this work with older browser I added a class hidden:

.hidden {display:none;}

In the script, whenever I set aria-hidden = "true" in the script, I also added the class hidden to the same selector:


I also removed it when I set aria-hidden = "false":


This makes the script much more robust in older browsers.

Also, not all older browsers treat the alert role as having aria-live=assertive as implied. Therefor I also used aria-live="assertive" for our alert. This makes the alert role more robust. However in some browsers it can make the alert be read twice (stutter). For very important messages, I felt it was worth having it read twice and working in more browsers.

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

Step 4: Manage focus and keyboard accessibility.

Initially the alert box is hidden and out of the tabbing order; however, as the alert role 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 has been taken care of.

Next let's deal with the keyboard accessibility. We made sure to use device independent events that can be triggered by the keyboard.

Firstly lets deal with the keyboard accessibility and make sure our jQuery selectors are device independent. In the code we have used mouse events such as "click()" to trigger the button function such as :


We need to add events as well for people who can not use a mouse.

The following function gives keyboard accessibility , so that pressing enter the button has focus (key-code 13) is the same as clicking the button with a mouse.

$("#go").keydown(function(ev) {
if (ev.which ==13) {

Thats it. Enjoy.


Author: Lisa Seeman

Accessibility 2.0

Managed by Lisa Seeman