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

computeAccessibleName ignores text inside of shadow DOM #768

Open
nolanlawson opened this issue Oct 26, 2021 · 4 comments
Open

computeAccessibleName ignores text inside of shadow DOM #768

nolanlawson opened this issue Oct 26, 2021 · 4 comments
Labels
help wanted Extra attention is needed

Comments

@nolanlawson
Copy link
Contributor

nolanlawson commented Oct 26, 2021

Thank you for writing this library! It's great to see a battle-tested solution for computing accessible names and descriptions. 🙂

I noticed, though, that when text is inside of the shadow DOM, it appears that computeAccessibleName ignores this text. Here is a CodePen to demonstrate.

Note that the Chrome Accessibility DevTools show the text inside of the shadow root as well as the text outside of the shadow root, since the browser uses both to compute the accessible name:

Screen Shot 2021-10-26 at 9 15 34 AM

In the case of open shadow roots (the most common kind), it should be possible to traverse shadow boundaries and collect the text inside of shadow roots.

@eps1lon
Copy link
Owner

eps1lon commented Oct 29, 2021

Thanks for the report.

This makes sense to me intuitively but it's not very clear from the ACCNAME spec.

Though this may just be an implementation choice or concern for aria-html i.e. is the shadow tree part of the "textual content" and not just textContent? Or should "each child" include traversing the shadow tree?

So while this is trivial to fix for this particular issue, I have no idea how this interacts with more complex shadow trees. Seems like this is still of an open issue in ACCNAME (w3c/accname#51 and w3c/accname#20).

I would appreciate it if somebody could find out how the shadow DOM fits into into story because the usual DOM APIs for text content or children do exclude it by default.

@eps1lon eps1lon added the help wanted Extra attention is needed label Oct 29, 2021
@nolanlawson
Copy link
Contributor Author

It's unfortunate that the accname spec isn't very clear on this. Based on how screen readers actually behave with shadow content, my intuition is that essentially the shadow tree should be traversed in normal tree order (with slots serialized in the order expressed in the shadow DOM, not light DOM). This aligns with their visual presentation as well.

@eps1lon
Copy link
Owner

eps1lon commented Oct 29, 2021

Based on how screen readers actually behave with shadow content, my intuition is that essentially the shadow tree should be traversed in normal tree order (with slots serialized in the order expressed in the shadow DOM, not light DOM). This aligns with their visual presentation as well.

Would definitely agree here. I think for now we could just walk the shadow tree for textual content and only consider textContent. The goal of this library isn't to match any specific devtools behavior or specific screenr reader behavior but matching existing specifications.

If there are some confirmed reports for at least two screen readers we can consider reading the textual content of the shadow tree. But I'm not comfortable fully applying all semantics to the shadow tree (e.g aria-labelledby). Just concatenating the text content of the shadow tree probably covers most usages of the shadow DOM.

@nolanlawson
Copy link
Contributor Author

I've found a related issue (repro) that may be slightly easier to fix. If two elements are co-located in the same shadow root, and one references the other with e.g. aria-labelledby, then the accessible name is not computed correctly, due to this line using the ownerDocument rather than the shadow root for getElementById:

.map((id) => node.ownerDocument.getElementById(id))

(node.ownerDocument.getElementById does not work, because the element with the ID is inside of the shadow root. But node.getRootNode().getElementById would work.)

If there are some confirmed reports for at least two screen readers we can consider reading the textual content of the shadow tree.

If you test the two demos I provided (here's the other one), you should see that both NVDA on Windows (Firefox and Chrome) and VoiceOver on MacOS (Safari, Chrome, and Firefox) read the button text contents, even the content inside of the shadow root. Ditto for the label+input in the above demo. I'm not sure if it's explicitly specified by the spec, but those screen readers at least (I haven't tested others) can read content inside the shadow DOM.

nolanlawson added a commit to nolanlawson/dom-accessibility-api that referenced this issue Apr 14, 2022
eps1lon added a commit that referenced this issue Apr 23, 2022
…ments in the same shadow root (#827)

* fix: fix co-located elements in shadow DOM

Partially addresses #768

* chore: fix prettier

* get rid of seemingly redundant "co-located" term

* add changeset

Co-authored-by: eps1lon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants