Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom labels #2

Open
mrego opened this issue Jul 1, 2022 · 4 comments
Open

Custom labels #2

mrego opened this issue Jul 1, 2022 · 4 comments

Comments

@mrego
Copy link

mrego commented Jul 1, 2022

Thinking about the topic from yesterday AOM meeting where we talked about Custom labels.

Doing some tests if we have the following example:

<x-label1 id="label1">
  <template shadowroot="open">
    <span id="foo">foo</span>
    <span id="bar">bar</span>
    <span id="baz">baz</span>
  </template>
</x-label1>
<input id="input1" aria-labelledby="label1" />

We get "foo bar baz" as label for the <input>. That's because how accessible name computation is done (which includes all children): https://w3c.github.io/accname/#mapping_additional_nd_te

With the current reflection proposal in this repo we could be more specified and just select one of the elements as the label:

<x-label1 id="label1">
  <template shadowroot="open" reflectsAriaLabelledBy>
    <span id="foo">foo</span>
    <span id="bar" reflectAriaLabelledBy>bar</span>
    <span id="baz">baz</span>
  </template>
</x-label1>
<input id="input1" aria-labelledby="label1" />

That way, we'll get "bar" as label for the <input>.

One question is if we could do something like this:

<x-label1 id="label1">
  <template shadowroot="open">
    <div aria-labelledby="bar">
      <span id="foo">foo</span>
      <span id="bar">bar</span>
      <span id="baz">baz</span>
    </div>
  </template>
</x-label1>
<input id="input1" aria-labelledby="label1" />

And tweak accessible name computation for custom elements, so it checks the first child for example, and use the information there. So in this example it ends up going to the bar element.

Currently accessible name computation doesn't work like that for regular elements, in order to avoid infinite loops while getting the element. Somehow with ARIA attribute reflection we can reference elements outside the Shadow DOM (see leobalter#15), so we could have a loop there too, maybe we should set some kind of condition anyway and do it only once for the first child of the custom element or something like that.

Anyway without entering in the final details, would this make any sense?

And going even further, would this proposal work for other things (unrelated to accessible name calculation), so we could do something like:

<input id="input" aria-activedescendant="list" />
<x-list id="list">
  <template shadowroot="open">
    <ul aria-activedescendant="i2">
      <li id="i1">item 1</li>
      <li id="i2">item 2</li>
      <li id="i3">item 3</li>
    </ul>
  </template>
</x-list>

WDYT?

CC @joanmarie

@Westbrook
Copy link
Owner

This certainly is interesting:

<x-label1 id="label1">
  <template shadowroot="open">
    <div aria-labelledby="bar">
      <span id="foo">foo</span>
      <span id="bar">bar</span>
      <span id="baz">baz</span>
    </div>
  </template>
</x-label1>
<input id="input1" aria-labelledby="label1" />

I'd be a bit worried about two things, the use of convention over configuration and the idea that it sounds that accessible name computation is the sort of changes that might get push back from browsers.

Convention

Cons

You've already seen the first effects of convention on your example, code that you would otherwise have left as three <span>s had to be wrapped in a <div> to complete the contract you are referencing.

  • What if the layout of my content requires the reflected/hoisted/exported reference to NOT be the first element?
  • What if the way that adding that element creates a group for the screen reader is not an acceptable alteration to the content that is being delivered?
  • Does this API having a shape that is inherently different than the delegation API make both APIs harder to learn and easier to make mistakes with?

Pros

I do like how this has less new API surface. At first blush, reflection/hoisting/exporting happens less than delegation might, which would reduce the regularity with which you'd need to so something like this, and the number of things you'd reflect at any one time, that could align with this being a nicer approach.

Accessible Name Computation

Maybe Cynthia could explain why she sees touching this as a third rail for this sort of change, but it's brought up over and again in the AOM syncs. However, I could see altering this computation, especially via convention than configuration as making it even more brittle, but I'm not a browser dev.

@mrego
Copy link
Author

mrego commented Jul 4, 2022

Another idea on this direction could be:

<x-label1 id="label1">
  <template shadowroot="open" aria-labelledby="bar">
    <span id="foo">foo</span>
    <span id="bar">bar</span>
    <span id="baz">baz</span>
  </template>
</x-label1>
<input id="input1" aria-labelledby="label1" />

This was somehow already proposed a while ago (see WICG/webcomponents#917). Though in that case it was for delegation, not reflection.

I guess one problem with this would be to update it, if you ever want to change that value (for example if you're using this for aria-activedescendant).

@mrego
Copy link
Author

mrego commented Jul 7, 2022

Another idea would be to avoid the need to create a lot of new properties like reflectsAriaLabelledBy, reflectAriaLabelledBy for each attribute. We could maybe go with some generic property that allows us to set a list of things if needed.

<x-label1 id="label1">
  <template shadowroot="open" reflects-attributes="aria-labelledby">
    <span id="foo">foo</span>
    <span id="bar" reflect-for="aria-labelledby">bar</span>
    <span id="baz">baz</span>
  </template>
</x-label1>
<input id="input1" aria-labelledby="label1" />

Or whatever wording we came up for these.

@Westbrook
Copy link
Owner

A catch all for the elements that are reflecting data seems like a great pairing for https://github.com/Westbrook/cross-root-aria-reflection/blob/main/cross-root-aria-reflection.md#thoughts-attribute-names-are-too-long I've added #7 to include this insight!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants