ARIA in HTML
On July 6 2021 the ARIA in HTML specification, that I co-edit along with Steve Faulkner and Patrick H. Lauke, became a W3C Candidate Recommendation Snapshot. As the W3C promoted in their invitation for implementation of ARIA in HTML:
[The ARIA in HTML] specification’s primary objective is to define requirements for use with conformance checking tools used by authors (i.e., web developers). These requirements will aid authors in their development of web content, including custom interfaces/widgets, that makes use of ARIA to complement or extend the features of the host language [HTML].
As of Septemer 30, the specification has moved to Proposed Recommendation (PR) (the status before a specification becomes an official W3C recommendation).
Maybe the mention of this specification and that it defines requirements for use of ARIA attributes within HTML is news to you? The specification was initially published as an evolving working draft by Steve Faulkner many years ago now (spun out of earlier rules within the W3C HTML specification), and has been a source of validation rules to the W3C HTML validator, among other conformance checkers. Aspects of the specification continued to be referenced in the W3C HTML specification (see allowed ARIA role, state and property sections for the linked
<span> element) even after ARIA in HTML became its own working draft specification. The HTML Living Standard, (thanks to work by Carolyn MacLeod) instead links to each element’s accessibility considerations for authors, rather than repeat portions of the spec.
Understanding ARIA in HTML
The ARIA in HTML specification does not define the features of HTML, or of ARIA. Nor does it define how HTML and ARIA map to accessibility APIs. Rather, it defines rules that conformance checkers can implement to keep authors from using ARIA unnecessarily, or to mitigate its usage in a way that would conflict with the strong native semantics and functionality of HTML.
Conformance checkers can surface these rules to authors through errors or warnings. Generally errors can be surfaced when authors do not conform to a ‘MUST’ or ‘MUST NOT’ rule, while warnings will surface when authors do not conform to a ‘SHOULD’, ‘RECOMMENDED’, ‘SHOULD NOT’ or ‘NOT RECOMMENDED’ rule.
An example of an error would be surfaced if an author had written the following markup:
<button role=heading aria-level=2> My text goes here </button> ...
<button> element is not allowed to have the
heading role specified, as the roles (the implicit
button role of the element, and the explicit
heading role set by the author) have conflicting characteristics. For instance, a
<button> is an interactive, keyboard focusable element used to allow users to perform an in-page action. Whether that be to submit a form, or to invoke a custom scripted function. A heading is meant to introduce the primary topic of a page or sub-section of a page. It is not expected to be interactive or keyboard focusable.
For this situation, the author’s choice to override the implicit semantics of the
<button> element could result in unnecessary uncertainty for users. Is this meant to simply be a heading, or is this an author not understanding that an element can’t have dual roles? If the former, why is it focusable? Why is it (potentially) being announced as a “clickable” heading by a screen reader? Why can’t the Space key be used to scroll the browser viewport when the element is focused, especially since no action occurs? Or arguably worse, why does hitting Space key result in an action occurring when a “heading” is focused?
To rectify the above, an author could instead use one of the following markup patterns.
First, if the heading was meant to be a standard heading, then rather than slathering on extra ARIA attributes, change the underlying element. No ARIA necessary.
<h2> My text goes here </h2> ...
Or, second, if the element was meant to be exposed as both a heading and a button (a common pattern used within accordion widgets), then a heading with a nested button would have been the better pattern to follow.
<h2> <button ...>My text goes here</button> </h2> ...
Information on errors and ARIA misuse regarding invalid nesting
In the previous markup sample, the
<button> is placed within the heading. The reverse (a heading within a button) is invalid as HTML specifies that only Phrasing content (excluding interactive elements and elements with
tabindex=0) are allowed as descendants of a
<button>. Additionally, an element with a
button role (either implicitly exposed by the
<button> element, or by explict author use of the
role=button ARIA attribute) is to treat its children as “presentational”. This means that any element nested within a
role=button should have its accessibility semantics suppressed from appearing in the browser’s accessibility tree.
The ARIA in HTML spec provides information about the allowed descendants of elements which have explicitly defined ARIA roles. The general guidance here is authors must follow each role’s allowed and required descendants, as defined by the ARIA specification. Additionally, if an HTML element (A) has specific allowances for what descendants it may have, then if an HTML element (B) has been given an explicit role to communicate itself as element A, then generally the descendant allowances of A now apply to element B.
In other (shorter) words, the following is an example of author misuse of ARIA, as links are not allowed descendants of a button:
<button> <span role=link>...</span> </button>
When conformance checkers surface a warning for an author’s use of ARIA in HTML, it’s because the author used ARIA in a way that is unnecessary. Or, it was used incorrectly but in a way where the user impact will be either low, or non-existent. Regardless of the reason, the warning serves to inform the author that they should look into what’s being flagged and make their own choice of whether to live with the warning, or adjust their code to take care of it. Unfortunately, a common misconception of authors is that they need ARIA to make their content accessible. And while some incorrect or inaccurate use may end up being benign due to user agents (browsers or AT) ignoring the unnecessary ARIA, without warnings of unnecessary misuse, misuse is more apt to remain cemented as “this is how you do accessibility” rather than “what you’re doing is either wrong or unnecessary. Let’s update this to make it simpler/better/etc.”
One of the most common warning authors can encounter would be from specifying redundant roles. For instance:
<a href=... role=link>...</a>
<a> with a valid
href implicitly has an ARIA
role=link. To specify an explicit
role=link is unnecessary in this instance. Similar for
<input type=checkbox>, etc. These elements have their implicit ARIA roles defined in HTML AAM, and have widespread implementation by browsers – even the elements introduced in HTML5.
That said, there can still be instances where authors may need to specify an explicit role on an element that would (should) normally expose that role implicitly. This could for a few reasons. – such as lingering bugs or gaps in implementation of an element’s accessibility mapping, or to counter how browsers and assistive technologies will interpret certain patterns that have been identified as being problematic for users.
Regarding the bugs or gaps, it was necessary to add, for example, an explicit
role=main to a
<main> element to ensure it would be consistently exposed in legacy browsers (i.e., Internet Explorer). But as time moved on, the need to do this decreased as assistive technologies would bridge the gaps of IE11’s partially implemented accessibility tree to what needed to be exposed to users.
A modern example of where one might need to explicitly specify an implicit role, would be to force WebKit (Safari) to expose list semantics when default list markers are removed, or to ensure that a
<table> and its table-element descendants will be properly exposed if their CSS
display properties are alterted (commonly done to create ‘responsive’ tables).
The above are considered “NOT RECOMMENDED” by ARIA in HTML, because in most situations the explicit declaration of the implicit role is unnecessary. This isn’t saying it’s entirely disallowed, but if you’re doing it, it should be because you have a legitimate use case that necessitates it.
Not just roles
The ARIA in HTML specification also defines usage for certain
aria-* attributes which have corresponding native HTML equivalents. A common misconception with authors is that ARIA attributes always take precedence over native HTML mappings. While that is true for an element’s role, HTML attributes take higher priority to equivalent ARIA attributes.
Consider the following:
<button disabled aria-disabled=false>...</button>
aria-disabled attribute would indicate that the
<button> is meant to be in the enabled state, the
disabled attribute not only communicates state to the accessibility tree, but it also has implicit functionality to remove the
<button> from the focus order of the web page, it disallows it to be clicked by pointer devices (mouse, touch, etc.), and its user agent styling “dims” the button by default.
Regarding the above example, as well as the other attribute rules defined in the specification, conformance checkers can surface warnings or errors to inform authors that their markup is either unnecessary, or that attribute values are in opposition to each other, which is likely a bug with their markup, and not their intent for the element.
The specification reaching
Candidate Recommendation Snapshot Proposed Recommendation status is not the end, by far. As the features of ARIA and HTML continue to evolve, so too will the ARIA in HTML specification. The latest Editor’s Draft will be where you can find the most up to date rules for using ARIA in HTML. Note that any new and updated rules in the Editor’s Draft may not be implemented in every conformance checker, but these rules can give authors a sense of what will be implemented in checkers going forward. It doesn’t hurt to be ahead of the curve, after all!