Rules & Exceptions

There are five main rules (and a few exceptions) to using ARIA:

Rule #1: Use a native HTML element or attribute

If you can use a native HTML element or attribute with the SEMANTICS and BEHAVIOR you need already built in, then do so. Instead of re-purposing an non-semantic element by adding ARIA role, states, or properties to make it accessible.

REAL LIFE SCENARIO:  A real dog is better than a stuffed (fake) dog any day of the week.

Instead of doing this:

<div role=”button”>Click Me</div>

Will render as:  

Click Me

Do this instead:

<button>Click Me</button>

Will render as:  

The browser itself does not know that the <div> with a role of “button” is a button, only its accessibility API does.

EXCEPTIONS:
There are times when this may not be possible:

Rule #2: Do not change the native element semantics

Unless you really have to, do not change native element semantics.

EXAMPLE:
Instead of doing this: [CHANGE WITH ANOTHER EXAMPLE LATER]

<h2 role="tab">heading tab</h2>

Do this:

<div role="tab"><h2>heading tab</h2></div>
NOTE: By KEEPING the current native semantic element (e.g., h2) and WRAPPING it with a generic non-semantic element (e.g., div) with the role you need (e.g., tab) will cause the top level non-semantic element to have the role instead.
EXCEPTIONS:
There are times when this may not be possible:
IMPORTANT NOTE:
It is important to remember that an ARIA role will OVERRIDE existing NATIVE HTML SEMANTICS (meaning) ROLE but will NOT CHANGE its DEFAULT BEHAVIORS, STATES, or PROPERTIES to make it look or act differently. Hence, ARIA will affect what is reported to a screen reader or other assistive technology.

EXAMPLE:

So, this link:

<a href="#" role="button">My Link To Button</a>

Will render as: My Link To Button

Becomes a button in the accessibility tree:

<button>My Link To Button</button>
However, because the link was “told” to be take on the role of a button now, to make it behave like a button, you will have to:

<a href="#" style="border: 2px solid red; padding:10px; background-color:blue; border-radius: 20px; color:white; text-decoration:none;" onClick="alert('Hello World')">My Link To Button</a>

Will render as:   My Link To Button

Conversely:

While this button:

<button role="heading">Text</button>

Will render as:

Becomes a heading in the accessibility tree:

<heading>Text</heading>
This heading still:

NOTE: Not exactly want you would want to do, but this illustrates this concept easily.

REAL LIFE SCENARIO: Just because I call you a lion, tiger, or bear does not make you a lion, tiger, or bear. However, you could “add on” some of these animal behaviors to mimic them (e.g., you could roar like a lion).  For you city folks, just because a cat has her kittens in an old oven in your backyard, does make them biscuits.

TIP: Follow the principle of the duck test – "If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck" – suggests that something can be identified by its habitual characteristics.  So, if it looks like a button, acts like a button, then it probably is a button.

EXAMPLE:
If you want to make the <h1> element act like a button:

Don’t do this:

<h1 role=”button”>Text</h1>

Do this instead: Wrap the text in a span element with a role of button inside of the <h1> element

<h1><span role=”button”>Heading</span></h1>

Or better yet, do this: Wrap the text in a semantic button element inside of the <h1> element

<h1><button>Heading</button></h1>
NOTE: Again, not exactly want you would want to do often but this illustrates this concept easily.

Rule #3: ARIA controls must be keyboard accessible.

All interactive ARIA controls must be keyboard accessible.  If you create an interactive control for a widget that can be:

A user must be able to navigate to the control and perform an equivalent action with the keyboard. These controls must be programmed via script (e.g., JavaScript) to respond to standard keyboard or keyboard combinations.

EXAMPLE:
If you assign a role = “button” to an element, that element must be able to:

Refer to the Design Patterns and Widgets and Developing a Keyboard Interface for more details.

Rule #4: Do not use role=”presentation” OR
aria-hidden=”true” on focusable element.

Using either role=”presentation” OR aria-hidden=”true” on a focusable element will result in some users focusing on nothing.

So, if you do this:

<button role=”presentation”>Hello World</button> OR <button aria-hidden="true">Hello World</button>

It will become this on the accessibility tree:

<>Hello World</>

Elements that don’t require children (e.g., heading element -  <h1>) will not have the semantics of their children elements removed. However, elements that require children (e.g., bullet list <ol> and <li>) will have their semantics removed.

REAL LIFE SCENARIO: Adoptive children will not have the same DNA as their parents.

Likewise, hiding a visible element from a screen reader is something that you would not normally do. However, if the element is purposefully hidden and cannot be interacted with, it is OK to use the aria-hidden state.

EXAMPLES:

Don’t do this:

NOTES:

Rule #5: All ARIA elements must have accessible name

All interactive ARIA elements must have an accessible name based on its API accessible name (or equivalent), or its property has a value.
EXAMPLE:
Instead of doing this:

<label>user name</label><input type="text">

While the input field has a visible label, it does NOT have an accessible name.
Do this:

<label>user name <input type="text"></label>

or do this:

<label for="userName">user name</label><input type="text" id="userName">
Notice there are two ways to cause the element to have an accessible name.

NOTE: A div element regardless of what role is assigned to it is not an HTML labelable element.  For example, <label> user name</label> <div role=”combobox”></div> will not yield an accessible name.