-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
.elementInternals accessor property #11040
Comments
Thanks for the issue @WilcoFiers! The point of ElementInternals being only accessible once via Given (my understanding of) the aim of axe-core is to automate accessibility testing I would offer that asking for ElementInternals to be exposed might be the wrong layer to be looking at. Perhaps more precise problem statements such as "we need to access the computed role", "we need to access the computed describedby elements" are more pointed, and perhaps better resolved in a forum like https://github.com/WICG/aom. |
I recommend looking at whatwg/dom#1290 (comment) for the possible solution space here. As with shadow roots we want to preserve encapsulation here and thus cannot give unfettered access. WebDriver access seems very reasonable however. |
@keithamus As I explained, a proposal for getting a computed accessible name, role, and states exist. It is unlikely to ever get traction because there are significant performance problems that can occur from implementing such a proposal. It also doesn't work for tools like axe because it doesn't just need to know the end result of a computed state, it needs to know how a state is computed so it can accurately communicate why a problem occurred. @annevk I'm not sure I understand. These tools are built to run in the DOM. How is using WebDriver a reasonable option? |
I'm afraid they'll need to use an extension or some such instead then. We generally don't add APIs to the web platform solely for testing. And in this case that would also go against other goals, such as offering encapsulation. |
That really isn't an option. Tools like ANDI and HTMLCodeSniffer are built as bookmarklets because that's often the only thing an accessibility tester is allowed to run. That work is often done on internal machines that are so locked down even installing extensions isn't possible, let alone running WebDriver. Other DOM-anywhere tools like axe-core and Equal Access are built this way so they can be used without tying an organization to one specific testing solution. Same tool in all your browsers, your Selenium Cucumber tests, the other team's Puppeteer tests, etc. It isn't just limited to Chromium because that happens to have CDp access in its extension, or Playwright because of its accessibility tree dump. It doesn't suddenly break your accessibility tests because browser X decided that in the next version display:content elements suddenly can be in the accessibility tree or whatever. I agree with you on the principle. it is perfectly reasonable for the DOM not to have APIs solely for the purpose of automated testing. But accessibility testing is not automated testing. The principle doesn't apply here. Most accessibility work is done on staging or production, by humans. This is not the same thing. A critical issue is that it doesn't just prevent testing elements with ElementInternals. Because there's no way to check if an element has internals, every custom element has to be treated like a black box. That has implications for every custom element, as well as any element that may include a custom element in its name or any of its ARIA props. For example, there is no DOM methods that can now tell you if the following is an input with an empty label: <label>
<my-elm></my-elm>
<input />
</label> |
The principle definitely applies here, it doesn't really matter if the testing is manual or automated. It's still testing. Extensions are also more interoperable now than they have ever been so I doubt a solution in that place would lock you down to any particular browser. |
With all due respect, that's hardly an answer. Even if browser extension interoperability was good enough for this, which it isn't, that doesn't matter. You're completely stepping over the fact that these tools need to run in environments where getting a browser extension installed is not an option, and that |
I'm just telling you that those tools will not be able to do this without some kind of non-web-exposed API, be it from an extension or WebDriver. It's very much the same as with shadow trees. If you can guarantee the scripts of these tools run first you could patch |
I think shadow trees are a good comparison, but there is a critical difference between shadow trees and This distinction is a very big deal for accessibility testing in practice; an overwhelming majority of actual shadow DOM usage today uses Would a proposal for an |
It seems to me that the way you stated problem makes this problem over constrained. The best way forward is probably for you to define some kind of convention that components can adhere to and rely on that convention. |
The specific use case in question is "tools whose primary purpose is to detect when authors have failed to follow accessibility conventions correctly." I don't think it would be a very useful way forward for tools like this to rely on authors having correctly followed an accessibility-related convention. |
That problem statement is over-constrained. Such a tool cannot really exist coherently with the world in which a proper encapsulation exists for element internals. |
That's exactly the point. The encapsulation of element internals, without an opt out (like open shadow DOM), without even a way to detect whether internals are used, prevents correct accessibility testing of all custom elements in many of the most popular accessibility tools. So that's the request, can we come with some solution that prevents that? |
Surely if we implement an opt-out but no one uses it you're left with the same problem? Or perhaps even worse, as the tooling now needs to lobby individual component authors to opt-out for their code to pass the tooling? I am still concerned this isn't really addressing the concrete problem statement. We're one or two steps away from "I'd like to introspect the accessible role" and into "I'd like authors to opt-out of encapsulation of internals so that I can use internals to introspect the accessible role". |
This is true and would be a risk, but based on current data about open vs closed shadow dom usage (where ~94% of usage is open rather than closed), we think it's likely that component authors would mostly decide in practice to use an open approach. I do agree that if the mechanism were strictly opt-out and defaulted to closed, this would definitely be a higher risk than with
This is a fair concern, and we're definitely open to alternate approaches. But I want to reiterate the point @WilcoFiers made earlier that "I'd like to introspect the computed accessible role" is not the problem statement, either. It is not enough for accessibility testing tools to be able to query the computed accessibility properties; we need to be able to inspect how those properties are getting their values. There are two main reasons for this:
I'd like to explain 1 a bit better with an example. Consider the following snippet: <label>
<custom-icon type="star"></custom-icon>
<input type="checkbox" />
</label>
<label>
<custom-icon aria-label="from attribute" type="star"></custom-icon>
<input type="checkbox" />
</label>
<script>
class CustomIconElement extends HTMLElement {
constructor() {
super();
const type = this.attributes.type.value;
const icon = { star: '★' }[type]
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `<span aria-hidden="true">${icon}</span>`;
this.internals = this.attachInternals();
this.internals.ariaLabel = type;
}
}
window.customElements.define('custom-icon', CustomIconElement);
</script> This is a real example today of a case where on the surface you'd think accessibility test tools could get away with testing the accessible names of the checkboxes by using a hypothetical First, as of writing, the stable versions of different browsers produce different output for the first checkbox (Chrome 133 says Second, the first This isn't a rare one-off case; this is just the first example I came up with in ~10 minutes of playing with This is the concern that is motivating us to ask for "inspecting what the user specified" rather than "inspecting what the browser calculated". |
What problem are you trying to solve?
ElementInternals provides several powerful options for setting accessibility related properties. These include role, various ARIA states, and labels. It is critical for accessibility test tools to be able to learn about this information. Many such tools, including axe-core (and thus Lighthouse, Accessibility Insights, etc.), IBM Equal Access, ANDI, and HTML Code Snipper are built to run directly in the page, and so only have access to native DOM features.
For these tools to work out accessibility information about custom elements they need to know 1. if an custom element has ElementInternals attached, and 2. what is on that ElementInternals object.
What solutions exist today?
There is no solution today. We've considered different options but none of them really work.
window.getComputedAccessibility()
. This was proposed as an alternative method for accessing accessibility information. This proposal looks unlikely to happen as it creates potential performance problems in browsers. Even if this eventually gets implemented, a direct accessor allows accessibility tools more direct access.Override Element.attachElementInternals: This can only work if the tool can be loaded on the page before scripts are executed. This cannot be done reliably. Many such tools defer loading until they are needed to prevent unnecessary adding load time when they are not needed.
Look to see if one of the element's properties has an instance of ElementInternals stored on it. Unfortunately looping over an element's custom properties to find what's on it triggers getters, which can have unforseen side effects. This also only works if the ElementInternals is stored as a public property, which is by no means guaranteed.
Call
.attachElementInternals()
to see if one is attached. That only tells us if ElementInternals is not attached, not what's on it. It also could prevent a delayed attachment from happening, creating unforeseen problems in the page.How would you solve it?
Add a new
.elementInternals
property toHTMLElement
. If there is an ElementInternals attached, this property returns the ElementInternals object. If not, the property returnsnull
.This would be consistent with how the
.shadowRoot
property works for attached shadow DOM trees. Looking at GitHub search,.elementInternals
is used by some tools so if we want to avoid conflicts with existing perhaps.attachedElementInternals
, I get no results for that.Anything else?
In axe-core the lack of support has been raised multiple times. Currently the open issue has more thumbs up than any other open issue.
The text was updated successfully, but these errors were encountered: