-
Notifications
You must be signed in to change notification settings - Fork 23
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
Add steps for shadow roots and slots #167
Conversation
Just chatted with @spectranaut – the suggestion was that "displayed child nodes" is probably the wrong phrase here, and maybe "rendered child nodes" is more accurate. I'm happy with either one; naming things is hard. 🙂 |
@jcsteh can you please look at this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some diffs so that we can re-review with @spectranaut's suggestion.
I'm not sure this addresses all of #51 since the submitter asked about aria-labelledby, which would presumably use a static element array when pointing into the shadow root. This is a great start, but an explicit mention of that new technique needed near the labelledby stage of the Name Computation?
Co-authored-by: James Craig <cookiecrook@users.noreply.github.com>
Co-authored-by: James Craig <cookiecrook@users.noreply.github.com>
Co-authored-by: James Craig <cookiecrook@users.noreply.github.com>
Co-authored-by: James Craig <cookiecrook@users.noreply.github.com>
Co-authored-by: James Craig <cookiecrook@users.noreply.github.com>
Co-authored-by: James Craig <cookiecrook@users.noreply.github.com>
The current
I think potentially there is nothing Perhaps this should go into the definition of an IDREF? I see that in the aria spec, it says:
It seems to me that this should read "in the same document or shadow root." |
OTOH there is the related question of what happens if a (Previous, erroneous comment)Whipping up a quick CodePen, and looking at the Chrome/Firefox Accessibility DevTools and VoiceOver+Safari, it looks like:
On second thought, I think my current PR language matches Chrome's and Safari's behavior – I've opened a separate issue to track this: #173 |
Just grokked this point. For IDREF reflection (whatwg/html#7934) – i.e. I think potentially this could be handled in a separate PR, since it's not strictly about shadow DOM. E.g. with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Nolan, your right this change should have WPT tests, as that is how we currently keep a list of tests for accname. Here is an example test: https://github.com/web-platform-tests/wpt/blob/master/accname/name_text-title-manual.html
Let me know if anything is not straightforward, but you might be able to get the gist of the test by looking at it and others. These test what the browser exposes in the native API, which you can see in the ATTAcomm
object. You would just want to make a new file, new title, some example html (give id="test" to the element you are testing the accname of), update the expected accname string for all APIs in the ATTAcomm json
.
If you write them I'll review them! :)
Also can you confirm, this algorithm represents what Safari and Firefox already do, but Chrome does not? And here is the chrome bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1374358 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks correct to me overall, aside from my inline question.
One of the challenges here is that this spec defines traversal in terms of the DOM. I'm not sure about other browsers, but Firefox walks the a11y tree when doing name computation, not the DOM tree, with the only exception being the case where a node isn't rendered into the a11y tree (display: none, etc.). I suspect Chrome does the same based on the slot bug, but I'm not sure about Safari. That makes the spec a little difficult to reason about from an implementation perspective. We don't have specific code to deal with slots in our name computation code because slots aren't rendered into the a11y tree at all. I suspect Chromium will need a similar fix. This also raises questions about how aria-owns is handled. Oof.
I guess we'd need a separate a11y tree traversal spec to deal with that, at which point we'd reference that from the AccName spec in terms of how we traverse. We don't have that yet, so I guess we'll need to talk in terms of the DOM for now.
index.html
Outdated
<li id="step2F.iii.b">Compute the text alternative of the <code>current node</code> beginning with step 2. Set the <code>result</code> to that text alternative.</li> | ||
<li id="step2F.iii.c">Append the <code>result</code> to the <code>accumulated text</code>. </li> | ||
<li id="step2F.iii.a">If the <code>current node</code> has an attached [=shadow root=], set the <code>rendered child nodes</code> to be the child nodes of the [=shadow root=].</li> | ||
<li id="step2F.iii.b">Otherwise, if the <code>current node</code> is a [=slot=] with [=slot/assigned nodes=], set the <code>rendered child nodes</code> to be the [=slot/assigned nodes=] of the <code>current node</code>.</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might well be missing something - this spec still really boggles my brain - but what excludes the <slot>
itself from being processed? The Chromium bug you filed is the precise example of this. We'll process the label as an idref, start walking its descendants as a result of 2h, recurse into the div, recurse to the slot as one of the child nodes of the div starting at step 2, and end up using the aria-label on the slot in 2d.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention is to tweak the children-traversal part of the algorithm to traverse into slot assigned nodes rather than child nodes. The slot itself is not excluded from processing; you're correct.
Based on w3c/html-aam#440 it looks like this should be handled in the html-aam
spec instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The slot itself is not excluded from processing; you're correct.
If I understand correctly, that means the Chromium bug isn't dealt with by this addition to the spec, correct? I'm not saying this isn't necessary, just clarifying for sure that it doesn't address the Chromium bug.
it looks like this should be handled in the html-aam spec instead?
This gets back to my comment about tree traversal. As I see it, it's less to do with the fact that a slot can't be named and more to do with the fact that the slot itself (but not its rendered children) should be skipped in the traversal in the first place. I realise this might sound like nitpicking, but I think it's important in understanding how browsers actually do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, that means the Chromium bug isn't dealt with by this addition to the spec, correct?
Correct, it's unrelated.
As I see it, it's less to do with the fact that a slot can't be named and more to do with the fact that the slot itself (but not its rendered children) should be skipped in the traversal in the first place.
That makes sense to me! I would ask @scottaohara if this is similar to other "HTML elements which do not support naming," or if <slot>
is a special case?
To add another wrinkle: the default UA stylesheet for <slot>
has display: contents
, but this can be overridden by the web author. So I'm not sure of the "namelessness" of slots is due to their being slots, or due to display: contents
.
Edit: apparently display: contents
should not affect the accessibility tree, but today it does? So it may be irrelevant to the <slot>
discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh blah. You're right: it's probably the fact that it has display: contents that excludes it from the Firefox a11y tree. As your test case shows, it does get exposed with display: block (because block elements have some semantic value by virtue of being block). That means that <slot aria-label="foo">
probably would get exposed in Firefox except for this bug.
So it does look like we'll need some explicit provision that slots shouldn't be exposed. I'm not sure if them not having a name is enough. That said, this is a bit tricky because <slot style="display: block;" tabindex="0">
does become focusable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that makes sense! To identify this bug, we could try adding WPT tests that set display: block
on the <slot>
.
That said, this is a bit tricky because
<slot style="display: block;" tabindex="0">
does become focusable.
Well, maybe <slot>
should be an element that can support naming? Unless #173 (comment) is the last word on this.
Note that I don't have a strong opinion; I'm just trying to determine the correct behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case someone does <slot style="display: block;" tabindex="0">
, we've gotten quite into the territory of author error correction.
If properly used, the slot element, along with elements like title, meta, template, etc... none of those should ever actually be exposed to a user and they should not be nameable. But, if you force these elements to be rendered by changing their CSS display property, then they essentially become 'generic' elements.
I think it makes sense to call out that if an author forces elements like these to be exposed to the a11y tree, then browsers should handle them like generics. But, again, I would stress this is correcting for author misuse and otherwise - if used properly - they cannot be named.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to call out that if an author forces elements like these to be exposed to the a11y tree, then browsers should handle them like generics.
@scottaohara Thanks for the feedback! Do you think this should be done in accname
or html-aam
? I'm wondering if it makes more sense to put it in html-aam
(per w3c/html-aam#440), since in accname
we're merely defining the tree traversal algorithm w.r.t <slot>
s and their assigned nodes, not whether <slot>
s can be named.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, i think this should be handled in html aam per the linked issue. i don't think accName should need to call this particular element out in any specific way. that's is what html aam can do.
Correct, based on my testing (#173), Safari and Firefox ignore the Based on w3c/html-aam#440 though, it seems like we want to cover "elements that cannot be named" (e.g. FWIW I did also open a PR to add some basic |
As discussed during AOM meeting, it's important that there is no JS API that exposes the computed accessibility names that emanate out of a shadow DOM since that would violate shadow DOM's encapsulation. And so far we've concluded there is none so we're good here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks okay to me now. Sorry I didn't get back to it after my initial review, but I agree my feedback has been addressed.
Of note, @nolanlawson, this will be testable in wpt/accname/name/comp_name_from_content.html once WPT #39604 lands. Please update the ReadMe in that same dir if you're the one making the change.
@cookiecrook No worries, thank you for the review! |
@spectranaut are your review comments addressed? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to move the name values back to their original steps. New numbered name
values should not be added; only named id
values like id="comp_something_logical_and_unique_to_this_step_even_if_it_is_moved"
.
index.html
Outdated
<li id="comp_name_from_content_for_each_child_set_current" name="step2F.iii.a">Set the <code>current node</code> to the child node.</li> | ||
<li id="comp_name_from_content_for_each_child_recursion" name="step2F.iii.b">Compute the text alternative of the <code>current node</code> beginning with the overall <a href="#comp_computation">Computation</a> step. Set the <code>result</code> to that text alternative.</li> | ||
<li id="comp_for_each_child_append" name="step2F.iii.c">Append the <code>result</code> to the <code>accumulated text</code>. </li> | ||
<li id="comp_name_from_content_find_child_has_shadow_root" name="step2F.iii.a">If the <code>current node</code> has an attached [=shadow root=], set the <code>rendered child nodes</code> to be the child nodes of the [=shadow root=].</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repurposing the "step2F.iii.a" here breaks the old permalinks. We kept those so that legacy deep links in would not break, but the legacy name
value should stay with the original reference (comp_name_from_content_for_each_child_set_current) and no new numbered name
values should be added.
New permalinks should used uniquely names id
values only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem. I changed it so that:
- New content has its own convention for the
name
- Pre-existing content (
comp_name_from_content_for_each_child
) has the samename
as before
GitHub doesn't do a great job with the diff, but permalinks should not be broken anymore.
index.html
Outdated
<li id="comp_name_from_content_return" name="step2F.iv">Return the <code>accumulated text</code> if it is not the empty string ("").</li> | ||
<li id="comp_name_from_content_for_each_child" name="step2F.iv"><em>Name From Each Child:</em> For each <code>rendered child node</code> of the <code>current node</code>: | ||
<ol> | ||
<li id="comp_name_from_content_for_each_child_set_current" name="step2F.iv.a">Set the <code>current node</code> to the <code>rendered child node</code>.</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<li id="comp_name_from_content_for_each_child_set_current" name="step2F.iv.a">Set the <code>current node</code> to the <code>rendered child node</code>.</li> | |
<li id="comp_name_from_content_for_each_child_set_current" name="step2F.iii.a"><!-- Leave legacy "step2F.iii.a" name value with this step, and don't add new name values. -->Set the <code>current node</code> to the <code>rendered child node</code>.</li> |
Perhaps we should even add comments like above so this is less likely to happen in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I did add a comment just to be safe:
Line 442 in a9cfa2e
<!-- The following section uses its own convention for the name attribute to avoid breaking existing permalinks for other sections--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Substantive change looks good, but editorial nits included.
Co-authored-by: James Craig <cookiecrook@users.noreply.github.com>
Co-authored-by: James Craig <cookiecrook@users.noreply.github.com>
(semi-randomly finding that now)
to
that should already pretty much take care of all the shadow DOM magic 🤔 |
@Jym77 I wasn't even aware that there was a concept of a "flattened tree." The link you provide is from the CSS spec – if there's something in the HTML spec, maybe we could reference it here to simplify the logic? |
BTW the WPT tests for this PR have already been merged: web-platform-tests/wpt#36541 Maybe we can merge and then refactor later as necessary? |
I'm not aware of anything like that in HTML (or DOM) specs. I agree it would be better to have this definition there rather than in CSS... From what I gather, CSS needs the concept for inheritance (second paragraph), but DOM or HTML never directly need that concept 😞 |
Realistically, accessibility implementations depend on layout rendering to some extent; e.g. display: none, visibility: hidden. Given that, it's probably not unreasonable to refer to a CSS concept here. FWIW, Gecko's accessibility engine internally uses the flat tree to build the accessibility tree and I assume other browsers might do similar. |
Blink does the same (technically the "layout tree builder traversal" which includes pseudo-elements, but otherwise just uses the flat tree traversal), since the whole |
I am not sure what we want to do about this so I'm going to mark it for the agenda, and read through it all in the meantime. |
This looks read to land, @jnurthen will resolve conflicts |
SHA: 67ca225 Reason: push, by spectranaut Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Fixes #20 and #93 (related: #51).
Clarifies how accessible names are calculated for shadow roots and slots.
I believe this is accurate in terms of what UAs actually do to calculate the accessible name inside of shadow roots and slots, although WPT tests are probably needed.
Implementation
Preview | Diff