Ten (10) ARIA Best Practices

The assistive technologies such as screen readers and speech recognition applications rely on HTML semantics of the page to convey the information such as heading, button, link, etc. The assistive technologies such as screen readers also use these semantic information to provide options to the users to quickly navigate in an application with special quick navigation keys apart from tab and arrow keys.

 

ARIA (Accessible Rich Internet Applications) is a specification from W3C which enables to provide the semantic information to the assistive technologies in custom built applications. It is very important to use the ARIA in a right way else it will not convey the intended information to the users.

 

This post will discuss 10 (ten) and basic best practices of using ARIA attributes in an application. These best practices have been identified by analysing various ARIA related accessibility issues found in various custom elements.

 

Please refer ARIA 1.1 specifications from W3C schools for the complete list of roles and properties.

 

Top 10 (ten) important and basic best practices

  • Ensure role and related aria-* attributes are on the same tag
  • Ensure the role and ARIA attributes are on the focusable tag for actionable widgets
  • The aria-label attribute should not be used without a role
  • The ARIA properties and roles should match the functionality and type of the element
  • All ARIA roles and attributes need to have valid and allowed values only
  • Avoid extra spaces and line breaks in the role and aria-* values
  • Do not use any roles without required parent / child roles
  • Do not use aria-hidden attribute on <body> tag
  • Use only allowed aria-* attributes for any role
  • Do not use aria-modal attribute

Ensure role and aria-* attributes are on the same tag

The roles conveys what is the element is and the aria-* attributes convey the state and property of the element. It is very important to ensure all the aria-* attributes for a given role are present on the same tag. The required and supported ARIA states and properties need to be on the same tag where the role has been provided. This ensures that the assistive technologies provide proper feedback to the users.

i.e., The role=”checkbox” conveys the assistive technology that this element is a checkbox and aria-label attribute helps the screen reader to read the label of the custom checkbox. If the role and aria-label attributes  are used in a different tags then assistive technologies will not convey the correct information to the users.

Wrong Example

<div aria-label=”Kannada”>
<span class=”customCheckBox” role=”checkbox” aria-checked=”false” tabindex=”0”> </span>
</div>

Correct Example

<div>
<span class=”customCheckBox” role=”checkbox” aria-label=”Kannada” aria-checked=”false” tabindex=”0”> </span>
</div>

 

Ensure the role and ARIA properties on the focusable tag for Actionable Widgets

The role and the ARIA-* attributes need to be on the focusable tag for all the actionable elements. If the role and ARIA attributes are provided other than the focusable tag then the assistive technologies may not convey the element type and state of the element while navigating with the tab. The change of the state of element is not read by the screen readers.

Example

All actionable elements such as <input>, <button>, <a href=””>, <select>, <option>, etc. are focusable elements any role and ARIA attributes need to be on the same focusable tags. For any custom elements providing tabindex=”0” makes the tag focusable hence all the role and ARIA attributes need to be on the tag which has tabindex attribute.

The aria-label attribute should not be used without a role

The screen readers read the information provided in the aria-label attribute. However using the aria-label attribute on an empty element without any role result in few screen readers not reading the information. It is necessary to provide a redundant valid role for the HTML element if you are using aria-label attribute to convey the information. Some screen readers does not consider the text in the aria-label if there is no accompanying role.

Correct Example:

<a href=”” class=”next” role=”link” aria-label=”Next”> <span class=”rightArrow”> </span> </a>

Please note by default screen readers recognize an anchor tag with href attribute as link. However redundant role link has been added to ensure the aria-label text is read by the screen readers on all platforms.

The ARIA properties and roles should match the functionality and type of the element

The role helps the assistive technologies to identify the type of the element such as button, menuitem, listbox, option etc. The aria-* properties conveys the state of the element such as expanded / collapsed, checked / unchecked, selected / not selected, etc.

Based on this information, user will be able to know the state of an element and use right kind of keystrokes. If the proper role is not provided for the element then it confuses the user and at times results in users using wrong keystrokes and expecting different action. This results in poor user experience and at times not able to use the element at all.

Example

An expandable button not having aria-expanded set to false initially with the role button is read by the screen reader as Just a button and user expects some action to happen that by activating the button and user will not know that there will be few more options presented.

 

All ARIA roles and attributes need to have valid and allowed values only

There are set of role and the values allowed for any aria-* attribute. Only these allowed values to be used for any role / aria-* attribute.

The aria-* properties take certain type of values only those type of values to be used else the information will not be considered by assistive technologies.

Examples

  • The aria-label takes only string.
  • The aria-labelledby takes only IDs. Using strings result in invalid.
  • The aria-setsize and aria-posinset properties takes only numbers (digits).
  • The aria-hidden, aria-expanded, aria-checked, etc., takes only Boolean values.
  • Last but not least ensure all attributes are spelt properly.

Please refer the W3C ARIA 1.1 specifications for the complete list of role and properties.

 

Avoid extra spaces and line breaks in the role and aria-* values

If there are line breaks or unnecessary spaces in aria-label property, screen readers read the same element more than one time with arrow key navigation. This confuses the user. Ensure always there are no unnecessary spaces and line breaks in the aria-label or any aria-* properties.

 

Wrong Example

The aria-label property has couple of line breaks between the text. When navigating with the screen reader arrow key navigation, the screen reader reads same checkbox many times.

<span role=”checkbox” class=”customCheckBox” tabindex=”0” aria-label=”I

 

Accept

 

The

 

Terms and conditions

…”></span>

 

The IDs referred in aria-* properties need to be space separated

There are few ARIA properties which take more than 1 ID reference to read the text such as aria-label, aria-describedby, etc. The IDs always should be space separated and there should not be any line break or extra spaces before and after.

 

Do not use any roles without required parent / child roles

Few roles are nested roles such as menu, listbox, grid, table, option, row, gridcell, etc. These roles need to be appropriately nested according to the specifications. Using these roles without the necessary parent / child roles always confuses the users and at times on mobile devices these just prevents users from navigating to the next elements with assistive technologies.

Example

  • For any table / grid following is the hierarchy of the roles grid > row > gridcell.
  • For any menu such as top navigation bar: menu > menuitem.

 

Please refer the ARIA authoring practices and ARIA 1.1 specifications.

Do not use aria-hidden attribute on <body> tag

The aria-hidden=”true” hides the element / text from the assistive technologies but the same will be visible on the screen. Setting aria-hidden to true on <body> tag makes the entire screen not read by the screen reader so never set aria-hidden attribute on <body> tag.

Use only allowed aria-* attributes for any role

Few attributes are supported by specific roles. If any unsupported ARIA attribute is used then the intended information will not be communicated to the users and at times the assistive technologies may interpret the element incorrectly.
i.e., The aria-pressed attribute is used only on role button to indicate it is a toggle button whereas aria-checked is used on checkboxes and radio buttons to indicate the selected option in the group.

 

Do not use aria-modal attribute

The aria-modal attribute is a valid ARIA 1.1 attribute. However, using the same results in VoiceOver on iPhone not reading the text on any modal or popups hence it is suggestable not to use aria-modal attribute anywhere.

 

References

ARIA 1.1 roles model:
http://www.w3.org/WAI/PF/aria-1.1/roles

 

ARIA Authoring Practices 1.1
http://www.w3.org/TR/wai-aria-practices-1.1/

 

Building an Accessible Button with Anchor Tag

Ideally it is good to reserve anchor <a> tag only for links and use <button> or <input type=”button”> tags for buttons from the accessibility and usability point of view. However, for various reasons we build custom buttons with <a>, <div> or <span>. The five (5) important things to be taken care to ensure that the button is accessible (ADA compliant) are discussed in this post. Ensure there is an appropriate keydown function along with the things discussed in this article.

Following are the considerations for developing an accessible button with anchor <a href> tag.

  1. Do not remove the ‘href’ attribute
  2. If it is a button provide role=”button”
  3. Provide href=”javascript:void(0);” for all the custom links / button with the href attribute
  4. Do not miss the semicolon (;) in the href value when provided with href=”javascript:void(0);”
  5. Do not provide hash (#) as the href value

Do not remove the ‘href’ attribute

The href attribute provides the following enhancements for the anchor <a> tag and this makes the coding simple.

  1. Provides keyboard focus while navigating with the tab key.
  2. Ensures that the elements gets activated with the Enter key along with the click.
  3. Changes the mouse pointer when hovered to indicate the element is clickable.

If you remove the Href attribute all the above functionalities are lost and <a> is just like <span> or <div> tag.

If the href attribute is removed then provide tabindex=”0” to make the element focusable with the tab key and CSS to indicate that the element is clickable on hover & focus. The element will not be activated with the enter key unless there is a function for keypress or keydown event.

If it is a button provide role=”button”

When the element looks like a button and the functionality is similar to a button then add role=”button”. If the role button is not added screen readers read them as link and user expectation for link versus button is different.

Provide href=”javascript:void(0);”

for all the custom links / button with the href attribute.

Provide href=”javascript:void(0);” instead of href=”#” and do not leave the href value empty.

Do not miss the semicolon (;) in the href value when provided with href=”javascript:void(0);”

With the JAWS screen reader turned on the buttons without semicolon (;) in the end of href=”javascript:void(0);” do not get activated with the enter or spacebar on IE 11. This just shifts the focus to the beginning of the DOM.

Do not provide hash (#) as the href value

Screen readers read href=”#” as same page link if there is no role specified hence the user expects that the element just moves the focus to in the same page. Many browsers scroll the page to the top when href=”#” is provided. This creates usability issues for the keyboard only users hence it is good to use href=”javascript:void(0);” both with and without role=”button”.

Additional Notes

Ensure event.preventDefault() has been called appropriately in the keypress / keydown function.

Ensure that the elements get activated with only Enter and space keys. There need to be a condition to check the pressed key and the action should happen only for enter and spacebar keys else the elements get activated even with tab navigation.

The keyCode for Enter is 13 and keyCode for spacebar is 32.

It is good to use keydown event instead of keypress event as there are some cross browser compatibility issues with the keypress event.