Summary

The use of ARIA roles, states and properties is necessary to ensure that custom controls are accessible to users of assistive technologies.

Techniques

Example

Example 1 — Identifying a custom button

The img element has the role button which will identify it as a button and not an image to assistive technologies.

<img src="controls/start.png"
    id="start"
    role="button"
    tabindex="0"
    alt="Start"/>
Example 2 — Maintaining state using JavaScript

The following simple example shows some of the considerations that must be paid attention to when creating a custom control: setting and unsetting callback functions, enabling and disabling the control, changing the visual appearance of the buttons. To make this image work with keyboards, the user's keypresses must also be monitored, and actions turned on and off.

<img src="controls/play.png"
    id="start"
    alt="Start"
    role="button"
    aria-disabled="false"
    tabindex="0"
    onclick="controlPlayback('start')"/>

<img src="controls/stop.png"
    id="stop"
    alt="Stop"
    role="button"
    aria-disabled="true"
    tabindex="0"/>

<script>
<![CDATA[
function controlPlayback(action) {

  var isStart = (action == 'start') ? true : false;
  
  var start_image = isStart ? 
           'controls/play-disabled.png' : 
           'controls/play.png';
  
  var stop_image = isStart ? 
           'controls/stop.png' : 
           'controls/stop-disabled.png';
  
  var start = document.getElementById('start');
    start.setAttribute('aria-disabled', 
              !start.getAttribute('aria-disabled'));
    start.setAttribute('disabled', 
              !start.getAttribute('disabled'));
    start.onclick = isStart ? 
            null : 
            function () { controlPlayback('start'); };
    start.setAttribute('src', start_image);
  
  var stop = document.getElementById('stop');
    stop.setAttribute('aria-disabled', 
              !stop.getAttribute('aria-disabled'));
    stop.setAttribute('disabled', 
              !stop.getAttribute('disabled'));
    stop.onclick = isStart ? 
            function () { controlPlayback('stop'); } : 
            null;
    stop.setAttribute('src', stop_image);
   
   if (isStart) {
    start.removeAttribute('onkeypress');
    stop.setAttribute('onkeypress', "if (event.keyCode==32||event.keyCode==13) { controlPlayback('stop'); }");
   }
   
   else {
    stop.removeAttribute('onkeypress');
    start.setAttribute('onkeypress', "if (event.keyCode==32||event.keyCode==13) { controlPlayback('start'); }");
   }
  
  alert(isStart ? 'Playback started!' : 'Playback stopped!');
}
]]>
</script>

The following buttons show this code in action:

Start Stop

Explanation

Although HTML provides a number of native controls (e.g., input, button, progress), developers often have to create their own equivalents to avoid the styling limitations or introduce specialized functionality.

The creation of custom controls can cause seriously accessibility issues, however, as the reliance on JavaScript to make the functionality work does not translate to assistive technologies by default. For one, when non-interactive elements like spans of text and images are made dynamic, assistive technologies will not be aware that the user can activate them. As well, as actions occur, the changes to the content are not reflected in the accssibility tree (i.e., the new content will not be available).

These scripting accessibility problems plagued early development on the web, but the introduction of ARIA roles, states and properties has helped mitigate many of the problems. Adding these attributes to custom controls makes assistive technologies of their presence and allows information about the current state of the control to flow through to users.

The following list describes the purpose of each of these types of attributes.

Roles

The ARIA role attribute is used to describe the function of a custom control (e.g., to indicate that an image functions like a button).

Custom controls require a role in order to inform assistive technologies about their purpose. This allows the assistive technology to present the element to users according to its expected use.

The supported roles for custom controls are as follows:


States

State attributes identify the current status of a control: whether it is currently checked or not, whether it is hidden, etc.

State attributes must be maintained by script as the user interacts with the control/content, otherwise the user may get locked out of functionality (e.g., unable to reduce the volume, unable to make important content visible, etc.).

The state attributes include the following:


Properties

Property attributes identify meta information about a control, such as the minimum or maximum value it allows or its place within a group.

Unlike states, properties are typically only set once when the content loads.

The property attributes include the following:


Related Links