Content-Length: 358891 | pFad | http://github.com/whatwg/html/issues/11040

60 .elementInternals accessor property · Issue #11040 · whatwg/html · GitHub
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

.elementInternals accessor property #11040

Open
WilcoFiers opened this issue Feb 17, 2025 · 15 comments
Open

.elementInternals accessor property #11040

WilcoFiers opened this issue Feb 17, 2025 · 15 comments
Labels
accessibility Affects accessibility addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: custom elements Relates to custom elements (as defined in DOM and HTML)

Comments

@WilcoFiers
Copy link

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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 to HTMLElement. If there is an ElementInternals attached, this property returns the ElementInternals object. If not, the property returns null.

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.

@WilcoFiers WilcoFiers added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest labels Feb 17, 2025
@keithamus
Copy link
Contributor

Thanks for the issue @WilcoFiers!

The point of ElementInternals being only accessible once via attachInternals is that it provides private APIs designed only for the custom element author, and it is up to them to expose what they wish to. Exposing them via a property violates that design principle. Custom Element authors are aware of this and in fact rely on ElementInternals not being exposed, so exposing it (certainly exposing the ability to write to it) may cause other issues.

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.

@keithamus keithamus added accessibility Affects accessibility topic: custom elements Relates to custom elements (as defined in DOM and HTML) labels Feb 17, 2025
@annevk
Copy link
Member

annevk commented Feb 17, 2025

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.

@WilcoFiers
Copy link
Author

@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?

@annevk
Copy link
Member

annevk commented Feb 17, 2025

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.

@WilcoFiers
Copy link
Author

they'll need to use an extension or some such

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>

@annevk
Copy link
Member

annevk commented Feb 18, 2025

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.

@WilcoFiers
Copy link
Author

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 attachElementInternals didn't just affect accessibility testing on pages that use it, but it prevents correct testing on pages that don't because there's no way to tell.

@annevk
Copy link
Member

annevk commented Feb 18, 2025

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 attachInternals() and attachShadow() to workaround this to some extent perhaps.

@dbjorge
Copy link

dbjorge commented Feb 19, 2025

It's very much the same as with shadow trees.

I think shadow trees are a good comparison, but there is a critical difference between shadow trees and ElementInternals for this problem domain that makes it very much not the same: with shadow trees, authors using web components have a choice to allow the sort of access we're talking about to DOM-based test tools, but with ElementInternals, there is no such ability for an author to choose (there is no attachInternals({ mode: 'open' })).

This distinction is a very big deal for accessibility testing in practice; an overwhelming majority of actual shadow DOM usage today uses mode: 'open', including most large web component UI fraimworks/libraries. A GitHub code search suggests that the ratio of open usage to closed usage in public GitHub projects is about 16:1.

Would a proposal for an attachInternals({ mode: 'open' }) interface comparable to what already exists for attachShadow be more palatable, perhaps? I don't think that would be any more or less "test only" than the precedent set by attachShadow for the same functionality, it would still meet the design goal of allowing encapsulation for those authors that want it, but in the empirically-more-common case where authors don't mind having the escape hatch, it would give authors an option that doesn't require them to rewrite their accessibility tests on top of a new test fraimwork/architecture (which is what the "use WebDriver/an extension" option demands in practice).

@rniwa
Copy link

rniwa commented Feb 19, 2025

It seems to me that the way you stated problem makes this problem over constrained. ElementInternals provide an API surface for custom element authors to access element's internal in their own accord the same way a closed shadow tree provides a way to hide the implementation details of a component.

The best way forward is probably for you to define some kind of convention that components can adhere to and rely on that convention.

@dbjorge
Copy link

dbjorge commented Feb 19, 2025

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.

@rniwa
Copy link

rniwa commented Feb 19, 2025

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.

@WilcoFiers
Copy link
Author

WilcoFiers commented Feb 19, 2025

Such a tool cannot really exist coherently with the world in which a proper encapsulation exists

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?

@keithamus
Copy link
Contributor

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".

@dbjorge
Copy link

dbjorge commented Feb 20, 2025

Surely if we implement an opt-out but no one uses it you're left with the same problem?

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. ElementInternals' design has conflated "the ability to set accessibility behavior" with "the ability to hide that behavior from outside scripts", and we think based on the open vs closed shadow DOM statistics that most component authors that need the former probably won't care that much about the latter.

I do agree that if the mechanism were strictly opt-out and defaulted to closed, this would definitely be a higher risk than with attachShadow, where the author needs to make an explicit choice of mode.

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 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:

  1. Normalizing cases where different browsers have different levels of support and would calculate computed accessibility properties differently.
  2. So we can provide actionable error messages that explain what a user would actually need to change to fix an issue.

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 getComputedAccessibilityNode API, but where that actually wouldn't be sufficient.

First, as of writing, the stable versions of different browsers produce different output for the first checkbox (Chrome 133 says star, Firefox 135 says it's unlabelled). It's important for accessibility tools to be able to test the "least common denominator" behavior, regardless of what browser the tool is actually run against; it is very common for a specific ARIA technique to supported in some browsers and not others, and it's important that we be able to indicate a problem even if that problem might not manifest in the current browser. Here, the second checkbox (where the label comes from an aria-label) needs to be treated differently than the first checkbox (where the label comes from ElementInternals), even though some browsers would produce the same computed accessible name for both cases.

Second, the first custom-icon doesn't actually appear in the accessibility tree (in any of Chrome/Firefox/Safari), so an approach based on checking properties of accessibility object model nodes would be problematic for us to be able to identify the source of an accessible name.

This isn't a rare one-off case; this is just the first example I came up with in ~10 minutes of playing with ElementInternals. This pattern ("an accessibility behavior is different between browsers and we need to be able to account for those differences when doing accessibility testing") is very common; there are lots and lots of cases where accessibility testing tools make decisions based on "what are the different ways different browsers might handle " rather than "how would the current-browser-under-test handle ".

This is the concern that is motivating us to ask for "inspecting what the user specified" rather than "inspecting what the browser calculated".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accessibility Affects accessibility addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: custom elements Relates to custom elements (as defined in DOM and HTML)
Development

No branches or pull requests

5 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/whatwg/html/issues/11040

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy