aom icon indicating copy to clipboard operation
aom copied to clipboard

ARIA versus AOM precedence for Custom Elements

Open cookiecrook opened this issue 7 years ago • 16 comments

@alice and others have mentioned the Custom Elements use case. Component creators want to define the default accessibility semantics yet still allow authors the ability to override the default semantics with ARIA.

<custom-button role="checkbox"> <!-- author overrides the default button role defined by the component creator -->

As such, it seemed like ARIA definitions would always need to take precedence over the AOM defined on a single node.

AOM vs ARIA precedence had been a matter of debate for many reasons, but Ryosuke had an idea at TPAC that may resolve this use case can still allow AOM to take precedence over ARIA. @rniwa, since this was your idea, please edit as needed. It's fine to make direct edits to this post or just respond as comments.

The idea is that both the shadowHost and the shadowRoot of the component can have an accessibleNode property.

Default component semantics would be defined on the shadow root:

shadowRoot.accessibleNode.role = "button";

…but authors using these custom elements could override the defaults by assigning content attributes on the shadow host.

<custom-button role="checkbox">

or

shadowHost.setAttribute("role", "checkbox");

If component creators needed to define strong semantics (E.g. Authors MAY NOT override this role), they could define AOM on the shadow host.

shadowHost.accessibleNode.role = "button"; // Strong semantics button role.
shadowHost.setAttribute("role", "checkbox"); // No effect on accessibility tree. Author would need to override this with AOM, not ARIA.

So, the precedence summary would be:

  1. AOM overrides ARIA on all Element nodes, include shadow host nodes.
  2. ARIA on the shadow host overrides AOM on the shadow root.

Default semantics for custom elements should be defined on the accessible node of the shadow root so that authors could override them with ARIA on shadow host.

cookiecrook avatar Dec 01 '17 02:12 cookiecrook

So the only way for ARIA to take precedence would be for an element to have a shadow root?

alice avatar Dec 01 '17 02:12 alice

At TPAC, I recall the web platform group discussing the idea of constructable stylesheet objects which would let a custom element style itself without requiring creation of a shadow root. This would be really useful for leaf elements (button, checkbox, radio, etc) which today only create shadow roots so they can insert a style element.

How would this proposal support those elements?

robdodson avatar Dec 01 '17 10:12 robdodson

Overall, I do like @rniwa's proposal, aside from @robdodson's comment, which I think is very valid. But the part that is still concerning with respect to the 2nd bullet from the summary:

  1. ARIA on the shadow host overrides AOM on the shadow root.

If AOM overrides ARIA on all elements, that means AOM on the shadow host overrides AOM on the shadow root. Which in principles sounds good, but, as today, all interactions with a CE are observable (via getter/setter for props, methods, and via observed attribute callback), while mutations on accessibleNode are not, unless the custom element defines a new accessibleNode property accessor to shim the CE's accessibleNode in order to observe mutations and carry on specific mutations on the shadow root, if needed.

To be more specific, <custom-button aria-disabled="true"></custom-button>, that is perfectly fine since we can observe that attribute and carry on some task. On the other hand, setting document.querySelector('custom-button').accessibleNode.disabled = true is not observable, unless I'm missing something.

I wonder if this is intentional?

caridy avatar Dec 02 '17 00:12 caridy

@caridy Thanks for the comment!

My suspicion is that if you need to watch for mutations of accessible properties (i.e. properties which would appear on AccessibleNode), something odd is happening.

In the example you gave, I would expect there to be a disabled property on the custom element which an author could set to mark it disabled; the element would then set its own accessibleNode properties to reflect the semantics. So in terms of mutation observers, you would observe the disabled property directly - analogously to any built-in element which sets its semantic properties without reflecting them to DOM attributes or properties.

alice avatar Dec 03 '17 23:12 alice

For using constructible stylesheet with a custom element, an equivalent feature for AOM would be phase 3 construction of accessible nodes. With that, you can associate both styles & default accessible nodes / ARIA values without constructing shadow root.

rniwa avatar Dec 04 '17 05:12 rniwa

@rniwa That sounds very similar to my proposal, then: ARIA would override the AccessibleRoot's properties.

alice avatar Dec 04 '17 05:12 alice

To be more explicit, the proposed order of precedence would be (in the order of the lowest to the highest):

  1. AOM on shadow root.
  2. ARIA on shadow host.
  3. AOM on shadow host.

This would allow authors to define the default role & ARIA values by AOM on shadow root while still allowing users of those components to override them via AIRA and AOM on shadow host, matching the behaviors of builtin elements.

rniwa avatar Dec 04 '17 05:12 rniwa

@rniwa Could you clarify how this works when there is no shadow root? How do we specify default, ARIA-overrideable semantics then?

alice avatar Dec 04 '17 05:12 alice

@alice : In the case there is no shadow root, then (1) is basically no-op so AOM would override ARIA.

rniwa avatar Dec 04 '17 05:12 rniwa

@rniwa Ok, so there would be no way to specify default, ARIA-overrideable semantics without a shadow root.

alice avatar Dec 04 '17 05:12 alice

@alice that would be done via constructible accessible node like constructible stylesheet.

rniwa avatar Dec 04 '17 05:12 rniwa

@rniwa So an element may end up with two AccessibleNodes attached to it, with different names?

alice avatar Dec 04 '17 05:12 alice

@alice : What do you mean by "with different names"? I'm not sure I understand what you're saying. What I'm proposing is to expose AccessibleNode on ShadowRoot (if there is one) in addition to AccessibleNode on Element.

rniwa avatar Dec 04 '17 05:12 rniwa

@rniwa I'm having trouble understanding https://github.com/WICG/aom/issues/98#issuecomment-348862020 -

an equivalent feature for AOM would be phase 3 construction of accessible nodes. With that, you can associate both styles & default accessible nodes / ARIA values without constructing shadow root.

(added emphasis)

Where/how would this constructible node be attached to the element? How would it be different from the accessibleRoot?

alice avatar Dec 04 '17 06:12 alice

@alice : That accessible node should be attached to the element as if there was a shadow root, and it's hanging off the shadow root. This is the way constructible style would be attached to a custom element without creating a shadow root but beaching as if it's a style inside the shadow root.

rniwa avatar Dec 04 '17 06:12 rniwa

IMO, AOM should be always higher than ARIA because we can only use ID reference in ARIA but it doesn't work with shadow DOM. When we set an aria-errormessage attribute to an element, it always can reflect to accessibleNode.errorMessage, but it may not work for the reverse case.

Now in spec ARIA is higher than AOM, so for example if the author has already set an error message target through aria-errormessage, it is impossible to update the target into an element in its shadow DOM.

I'm not sure if it is possible to let shadowRoot.accessibleNode and shadowHost.accessibleNode be just the same object.

So my suggestion is:

  1. AOM on shadow root & shadow host (of course including custom element without shadow DOM).
  2. ARIA on shadow host.

Just like an normal element.

However, any rules which can make the "error message" example above possible is acceptable for me.

Thanks. (I come from #114 )

Jinjiang avatar Apr 26 '18 12:04 Jinjiang