aom
aom copied to clipboard
ARIA versus AOM precedence for Custom Elements
@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:
- AOM overrides ARIA on all Element nodes, include shadow host nodes.
- 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.
So the only way for ARIA to take precedence would be for an element to have a shadow root?
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?
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:
- 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 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.
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 That sounds very similar to my proposal, then: ARIA would override the AccessibleRoot's properties.
To be more explicit, the proposed order of precedence would be (in the order of the lowest to the highest):
- AOM on shadow root.
- ARIA on shadow host.
- 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 Could you clarify how this works when there is no shadow root? How do we specify default, ARIA-overrideable semantics then?
@alice : In the case there is no shadow root, then (1) is basically no-op so AOM would override ARIA.
@rniwa Ok, so there would be no way to specify default, ARIA-overrideable semantics without a shadow root.
@alice that would be done via constructible accessible node like constructible stylesheet.
@rniwa So an element may end up with two AccessibleNode
s attached to it, with different names?
@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 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 : 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.
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:
- AOM on shadow root & shadow host (of course including custom element without shadow DOM).
- 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 )