w3c / html-aria

ARIA in HTML
https://w3c.github.io/html-aria/
Other
179 stars 48 forks source link

Do MUST requirements apply to all stages of document life-cycle #345

Open dd8 opened 2 years ago

dd8 commented 2 years ago

Do these conformance requirements apply throughout entire document life-cycle, or only some parts of it (e.g. after all scripts have run).

https://www.w3.org/TR/html-aria/#conformance

This is tied up with the issues surrounding WCAG 4.1.1: https://github.com/w3c/wcag/issues/770#issuecomment-907420698

There is a reference to document life-cycle in WAI-ARIA but it doesn't define the term:

Authors need to associate elements in the document to a WAI-ARIA role and the appropriate states and properties (aria-* attributes) during its life-cycle, unless the elements already have the appropriate implicit WAI-ARIA semantics for states and properties

https://www.w3.org/TR/wai-aria-1.2/#usage

Issues:

1) Do the conformance requirements in html-aria apply to the initial state of the document (i.e. when DOMContentLoaded fires after parsing is complete, but before any scripts have run). This is basically the state the W3 validator checks, so the question is tied up with conforming implementation exit criteria.

2) Applying conformance requirements to the initial state of the document means that documents which start off with HTML source containing non-conforming ARIA can't be made conforming via script. Note that this is case of fixing broken ARIA with more ARIA, so it's slightly different to fixing broken HTML with ARIA. An example of this is:

<!-- HTML source: aria-selected not allowed on implicit role=link -->
<ul class="tabs" data-tabs id="resource-tabs">
<li class="tabs-title is-active">
  <a href="#tab1" aria-selected="true">Tab 1</a>
</li>
</ul>
<!-- after scripts finish running #tab1 has been given role=tab -->
<ul class="tabs" data-tabs id="resource-tabs">
<li class="tabs-title is-active">
  <a href="#tab1" aria-selected="true" role="tab" aria-controls="tab1-list" id="tab1-list-label" tabindex="0">Tab 1</a>
</li>
</ul>

3) Deferring checks to "when scripts have finished running" requires a normative definition of "when scripts have finished running". This isn't straightforward - some web pages with real-time updates have scripts that never finish running (e.g. Twitter).

4) There's also a spec/implementation complexity issue with allowing an invalid initial state. There are a lot more invalid states than valid states (probably many orders of magnitude more). It would be difficult to make sure all transitions from an initial invalid state are well specified and well behaved. Related issues are: https://github.com/w3c/aria/issues/729 https://github.com/w3c/aria/issues/986

5) Are there any requirements on transitory states? (e.g. can a JS function add an aria-selected attribute to an <a> element before it sets role=tab) via code like this:

var ele = document.querySelector('a#tab1');
ele.setAttribute("aria-selected", "false"); // aria-selected not allowed on implicit role=link
ele.setAttribute("role", "tab"); // aria-selected is now allowed because role=tab

6) Some pages have transitory states that persist for a long time. For example, an ARIA table that loads content and roles via an XmlHttpRequest for each cell might take 30 seconds or more. During this period the AT is voicing a partially complete ARIA table.

patrickhlauke commented 2 years ago

quickfire takes:

There is a reference to document life-cycle in WAI-ARIA but it doesn't define the term

I would generally understand the life-cycle to be "from the moment the page/document is interactable/operable by the user". This generally means once the complete document and its necessary external resources have been transferred to the user agent, and the necessary initial scripts have been run. From that point on, until the document is unloaded. Not sure if this needs clarifying in the ARIA spec /cc @jnurthen

From this, the answer to 1 would be "once that state of the page being interactable/operable by the user has been reached". Noting that for the majority of websites/applications these days, just pointing the W3C validator at the URL has a very low rate of success of being representative of anything, as often you're just ending up validating the initial shell of a page/application before anything is actually constructed/loaded in as a separate document fragment dynamically/displayed. So validation for anything other than basic static sites these days is done by sending the serialised DOM of the page once it's in its "ready to be interacted with" state. doing it at any point before then is pointless.

2, 3, 4 should be answered by this as well.

for 5, you're seriously asking about a transitory state of like a millisecond or thereabouts? now, IF the delay between applying one attribute/role, and then another required one, was actually long enough to cause a situation where a user may experience the thing in its transitory state (like if it took a second or more), sure...that'd be a problem, and I'd file that under 4.1.2 when encountered. i wouldn't bother with pinning anything on 4.1.1 on this. but your code example takes this ad absurdum, as there isn't a way to set two or more of the roles/attributes EXACTLY at the same time (unless you ripped out the element entirely, rebuild it outside of the DOM, and then reinserted it, which is pointless DOM thrashing I'd say).

for 6. i'd say IF the incompleteness persisted for a very long time, enough to be perceivable by the user, then that'd be again a possible 4.1.2 concern. i wouldn't start dragging 4.1.1 into this.

dd8 commented 2 years ago

I would generally understand the life-cycle to be "from the moment the page/document is interactable/operable by the user". This generally means once the complete document and its necessary external resources have been transferred to the user agent, and the necessary initial scripts have been run.

One issue here is the mainstream screen readers run as separate processes, so there's the potential for asynchronous access before the document becomes interactable/operable. I believe that Safari has an 'isolated accessibility tree mode' which allows VoiceOver to access the accessibility tree on a secondary thread with JavaScript running on the main thread.

This is very implementation dependent, and depends on the browser internals and the interprocess-communication mechanism used by the platform accessibility API under the hood.

There's also the issue of in-page loading indicators and incrementally rendered large documents:

for 5, you're seriously asking about a transitory state of like a millisecond or thereabouts?

Flagging this up to illustrate 2 things:

For example, if everything after initial parse is done by mutation listeners that are role specific, there may be no listener for changes to aria-selected in the following example until the role is changed to tab, so the aria-selected setAttribute call is ignored:

var ele = document.querySelector('a#tab1');
ele.setAttribute("aria-selected", "true"); // aria-selected not allowed on implicit role=link
ele.setAttribute("role", "tab"); // aria-selected is now allowed because role=tab

This goes back to the question 4 - there's a lot more scope for things to go wrong in implementations when transitioning from or via invalid states. I don't think there's much wording in the spec about this, and I can't see any WPT tests for this, so there's a question mark over interoperability here.