leobalter / cross-root-aria-delegation

Explainer for the Cross-root ARIA delegation proposal
https://leobalter.github.io/cross-root-aria-delegation/
25 stars 3 forks source link

Delegation String vs IDREF attributes #19

Closed mrego closed 1 year ago

mrego commented 1 year ago

I believe we'll need to explain the differences between string attributes and IDREF attributes on the definition of the delegation proposal. So let's use some examples (with the current syntax on the explainer, though that's not the important part here).

String attributes

<x-input aria-label="My label">
  #shadow-root delegatesAriaLabel
  <input autoAriaLabel />
</x-input>

We could end up with something like <input aria-label="My label">, basically setting the attribute on the inner input, and that will work.

We might need to see what we do with the attribute in the custom element (x-input) in order to avoid screen readers reading it twice. But that's a problem for any kind of attribute and something we'd need to properly spec to avoid issues.

IDREF attributes

<label id="my-label">My label</label>
<x-input aria-labelledby="my-label">
  #shadow-root delegatesAriaLabelledBy
  <input autoAriaLabelledBy />
</x-input>

Here, we cannot simply set the attribute in the inner input like <input aria-labelledby="my-label">, that won't work as you cannot reference something from outside the Shadow DOM tree with an attribute like that. So for this we need to use element reflection that allows us reference things on the shadow-including ancestors. So we'd need to set the explicitly set attr-element/s to add this relationship into the a11y tree.

Then there's the question if we need/want to also preserve the relationships set with element reflection inside the shadow tree. Imagine that someone sets manually the relationship between the x-input and the label like:

<label>My label</label>
<x-input id="my-input">
  #shadow-root delegatesAriaLabelledBy
  <input autoAriaLabelledBy />
</x-input>
<script>
  document.getElementById("my-input).ariaLabelledByElements = document.getElementsByTagName("label");
</script>

In this case the label doesn't have an id, so we cannot reference it in a regular aria-labelledby attribute. But element reflection allows us to reference the label anyway in that case by setting the explicitly set attr-elements. My question is if we want to delegate that relationship somehow, so the inner input gets the proper label associated to it.

As mentioned before, the issue with the double speaking from screen readers is common to both types of attributes.

CC @leobalter @nolanlawson

nolanlawson commented 1 year ago

@mrego

Here, we cannot simply set the attribute in the inner input like <input aria-labelledby="my-label">, that won't work as you cannot reference something from outside the Shadow DOM tree with an attribute like that.

I thought that one of the main benefits of cross-root aria delegation is that this would work. As long as <label id="my-label"> is in the same DocumentOrShadowRoot as <x-input>, it feels like it should work. (Also note that it doesn't violate the ancestor/descendant restriction (https://github.com/WICG/aom/issues/192).)

Setting element.ariaLabelledBy is certainly a workaround, but I think we want to support the fully-declarative use case as well (e.g. for SSR with Declarative Shadow DOM).

My question is if we want to delegate that relationship somehow, so the inner input gets the proper label associated to it.

I think this should be supported, yeah. Delegating aria-labelledby should imply that setting ariaLabelledBy on the host also works.