-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Allow setting default accessibility semantics for custom elements #4658
Conversation
One thing that's strange about this approach is that ARIA roles are typically an intrinsic property of an element, not something that change over time. There is input element but that's more of an anomaly than not. I think it makes more sense to have this be an optional argument to |
Well, there's actually a lot of cases where things change. You can see https://w3c.github.io/html-aam/#html-element-role-mappings for details. The others are:
... well, you get the idea; I stopped at "L". Most complex controls, or controls that have relationships with other controls, need the ability to dynamically change their role. |
I don't know if this influences this decision but the ARIA spec states the following at http://w3c.github.io/aria/#roles
|
Hmm, thanks @jnurthen, that is interesting. The first half of the paragraph, about author behavior, is not as relevant. But the part about platform accessibility APIs not being able to adapt to role changes is quite relevant. Can someone who works on browser AT confirm that if I write <a>placeholder</a>
<script>
document.querySelector('a').href = 'https://example.com/';
</script> then AT users will forever see the If that's the case, then I guess custom elements aren't going to be able to do any better, and we do need to re-think the design away from a mutable property. |
@domenic that's not the best example as despite what the AAM currently says seems like browsers expose the have created a modded test case which tests, i think, what you were asking. no issue for AT. |
Ah, thank you! Well, perhaps I should just start testing those cases I listed myself, but do you know off the top of your head the answer for their analogues? E.g. <body>
<main></main>
<footer>I have contentinfo role to start with</footer>
<script>
document.querySelector("main").append(document.querySelector("footer"));
// now it should have no role
</script>
</body> or <img src="test" alt=""> <!-- presentation role to start with -->
<script>
document.querySelector('img').alt = 'a test image';
// now it should have img role
</script> ? |
@stevefaulkner I'm interested to know how you tested this? Are you looking at the internal browser representation of the tree, the Platform accessibility APIs or what is actually being presented to the user using (for example) a screen reader. |
If more investigation is required here, perhaps an issue can be used? That'll make reviewing the eventual text a little easier. |
I looked at acc API info, browser acc tree and navigated with JAWS and NVDA. I also created a second test case with a button to trigger the type change. Same result - SR's tested had no problem with the type change. |
@domenic commented:
The terms "default" and "native" are both correct and interchangeable in this context. One consideration is that neither "default" nor "native" has an elegant counterpart that describes its opposite. Using "implicit" and "explicit" is one way to make the two different concepts clear, though arguably those terms are harder to comprehend. The ARIA spec seems to use "default", "native", "implicit", and also "Host language semantics" without particular preference. Is it worth adding a definition of whichever terms are used, that explains the common alternative terms that are used interchangeably with them? Most people refer to "ARIA", but AIRC the official "WAI-ARIA" name was necessary because "ARIA" was already trademarked elsewhere. If it's possible to use "ARIA" in the prose but reference "WAI-ARIA" in the biblio, that would be the best of both worlds, if not I think it'll have to be the more awkward formal name. Using "semantics" or "accessibility semantics" if you want to put particular emphasis on it, to mean role, state and property information, is absolutely fine. |
My brief testing showed the same but before moving forward with assuming this text in the ARIA spec is now obsolete I'd like to get the opinion of developers of JAWS, NVDA, ORCA, VO (and others if we can find them). I've opened w3c/aria#986 to ask the question if the ARIA spec text is still accurate. |
@rniwa, this option has surfaced multiple times... we are not Ok with forcing the author of the component to register the component, that doesn't work for us, and does not work for many other folks that produce components that can be registered by their consumers with arbitrary tag names. |
That's an orthogonal issue. Custom element class can easily define a static method for ARIA role and whoever defines a concrete custom element could use that ARIA role via static method. |
source
Outdated
this._checked = false; | ||
this.addEventListener('click', this._onClick.bind(this)); | ||
|
||
<mark> this._internals.role = "checkbox"; |
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.
nit: In this code example, single quotes are used.
source
Outdated
|
||
<div w-nodev> | ||
|
||
<p>Each <span>custom element</span> has a <dfn>native accessibility semantics map</dfn>, which is |
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.
Maybe we should mention the initial content of native accessibility semantics map. It's empty initially?
6347136
to
f138256
Compare
@rniwa given the above input from accessibility folks about how native elements often experience role changes, do you think the API here is reasonable to allow custom element authors to achieve the same thing? We could also open an issue with that precise question on the ARIA repository to get more input. |
TL;DR - I think having a way to set a default role on a custom element would be nice, but we absolutely shouldn't exclude it from I do see You could argue that custom elements which have a visual appearance should always map to a single UI metaphor, but that seems overly restrictive to me. Also, given you can change In Blink, we have code to handle a role changing by destroying and re-creating the associated accessibility node, effectively doing what the ARIA advice suggests authors do themselves. WebKit also has code to handle a role change. It might be nice to have a way to set a default value for the value of -- [1] Perhaps that could also do something clever with other required ARIA attributes associated with that role? Though in practice, ARIA takes care of that by specifying default values where the attribute is not set. |
Adds a way to set default ARIA role, state & properties for custom elements through ElementInternals. These can be overridden with setting the ARIA attributes on the element directly. See whatwg/html#4658 for spec PR. Change-Id: I0caf6bc302445e48f4e0324513105eba3d6303a6
Adds a way to set default ARIA role, state & properties for custom elements through ElementInternals. These can be overridden with setting the ARIA attributes on the element directly. See whatwg/html#4658 for spec PR. Change-Id: I0caf6bc302445e48f4e0324513105eba3d6303a6
Adds a way to set default ARIA role, state & properties for custom elements through ElementInternals. These can be overridden with setting the ARIA attributes on the element directly. See whatwg/html#4658 for spec PR. Change-Id: I0caf6bc302445e48f4e0324513105eba3d6303a6
I find it a bit confusing that the definition of the attributes defined at https://w3c.github.io/aria/#dom-ariaattributes use "reflect" whereas here we use a different definition. It seems there should be some kind of abstraction that allows the object that includes the mixin to decide how they work and then the "reflect" definition can be used for elements (maybe, see w3c/aria#1058) and this definition can be used for internals. |
That's actually exactly what it does :). See the linked ARIA PR which sets up that infrastructure. |
…lementInternals, a=testonly Automatic update from web-platform-tests Add ARIA role, state and properties to ElementInternals Adds a way to set default ARIA role, state & properties for custom elements through ElementInternals. These can be overridden with setting the ARIA attributes on the element directly. See whatwg/html#4658 for spec PR. Explainer: https://github.com/alice/aom/blob/gh-pages/explainer.md#per-instance-dynamic-semantics-via-the-elementinternals-object Intent to Implement: https://groups.google.com/a/chromium.org/d/msg/blink-dev/b-cGz9c67pM/0zvBzjhrAAAJ Change-Id: I0caf6bc302445e48f4e0324513105eba3d6303a6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1709950 Commit-Queue: Rakina Zata Amni <rakinachromium.org> Reviewed-by: Alice Boxhall <aboxhallchromium.org> Reviewed-by: Kent Tamura <tkentchromium.org> Cr-Commit-Position: refs/heads/master{#685141} -- wpt-commits: 5c61f2493fe744dc9f3d08e1f5a80165f574cfa3 wpt-pr: 18223 UltraBlame original commit: a95eec38bb25d830da2c2414356d5904c8e99d6d
…lementInternals, a=testonly Automatic update from web-platform-tests Add ARIA role, state and properties to ElementInternals Adds a way to set default ARIA role, state & properties for custom elements through ElementInternals. These can be overridden with setting the ARIA attributes on the element directly. See whatwg/html#4658 for spec PR. Explainer: https://github.com/alice/aom/blob/gh-pages/explainer.md#per-instance-dynamic-semantics-via-the-elementinternals-object Intent to Implement: https://groups.google.com/a/chromium.org/d/msg/blink-dev/b-cGz9c67pM/0zvBzjhrAAAJ Change-Id: I0caf6bc302445e48f4e0324513105eba3d6303a6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1709950 Commit-Queue: Rakina Zata Amni <rakinachromium.org> Reviewed-by: Alice Boxhall <aboxhallchromium.org> Reviewed-by: Kent Tamura <tkentchromium.org> Cr-Commit-Position: refs/heads/master{#685141} -- wpt-commits: 5c61f2493fe744dc9f3d08e1f5a80165f574cfa3 wpt-pr: 18223 UltraBlame original commit: a95eec38bb25d830da2c2414356d5904c8e99d6d
…lementInternals, a=testonly Automatic update from web-platform-tests Add ARIA role, state and properties to ElementInternals Adds a way to set default ARIA role, state & properties for custom elements through ElementInternals. These can be overridden with setting the ARIA attributes on the element directly. See whatwg/html#4658 for spec PR. Explainer: https://github.com/alice/aom/blob/gh-pages/explainer.md#per-instance-dynamic-semantics-via-the-elementinternals-object Intent to Implement: https://groups.google.com/a/chromium.org/d/msg/blink-dev/b-cGz9c67pM/0zvBzjhrAAAJ Change-Id: I0caf6bc302445e48f4e0324513105eba3d6303a6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1709950 Commit-Queue: Rakina Zata Amni <rakinachromium.org> Reviewed-by: Alice Boxhall <aboxhallchromium.org> Reviewed-by: Kent Tamura <tkentchromium.org> Cr-Commit-Position: refs/heads/master{#685141} -- wpt-commits: 5c61f2493fe744dc9f3d08e1f5a80165f574cfa3 wpt-pr: 18223 UltraBlame original commit: a95eec38bb25d830da2c2414356d5904c8e99d6d
sketching ElementInternals Form-associated elements are now working. Remaining test failures in custom-elements/form-associated/ are: * whatwg/html#4658 hasn't made it into the standard yet, and ElementInternals-accessibility is all about that functionality. * ElementInternals-setFormValue hits many race conditions with our iframe order of operations. Isolating just the "submit this form with these custom elements, look at the query" part, the payload of each test actually does pass! Running the tests as written, we end up with different tests overwriting each other's elements and getting very confused. One problem is the about:blank double-load-event thing, but fixing that doesn't fix everything. * ElementInternals-validation doesn't work because we don't have form validation in general; I've commented the relevant stubs. * ElementInternals-form-disabled-callback fails on #25713.
Note that Mozilla considers this |
Sorry for the delay. I had been out on a medical leave for 4 months. We had some extensive internal discussions about this, and we now believe this is a pretty reasonable API. We'd like to see some sugar for defining the default role for a class of custom elements (e.g. maybe a static variable on class) but that could be tackled separately. |
e32a070
to
e95cc26
Compare
Awesome, thank you @rniwa! I've rebased this on master. It's still blocked on w3c/aria#984, but otherwise it should be ready to merge; any review is appreciated. |
cc @whatwg/a11y @whatwg/components (unclear if the OP notification worked as the bot that modifies OP isn't able to ping these groups) |
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.
Found two possible nits and pushed a fixup for the remainder.
1fba51f
to
2eb1db1
Compare
This WIP pull request drafts a mechanism for using ElementInternals to set a custom element's default accessible role, states, and properties. It builds on w3c/aria#984 and must not be merged before that dependency is ready.
Perhaps a separate issue, but one this PR makes more apparent: I think we should add some text in the custom elements section generally that encourages custom element authors to have a more formalized contract with their consumers, e.g. provide their own recommended content model, strong native accessibility semantics, etc. I touched on this briefly in the example but it should probably be somewhere more normative as well.
Things I could use reviewer feedback on (now resolved):
/cc @tkent-google @alice @stevefaulkner (your help as HTML-AAM editor would be especially appreciated) @whatwg/a11y @whatwg/components. I'm also happy to open an issue on w3c/webcomponents if folks think that would be helpful.
(See WHATWG Working Mode: Changes for more details.)
/custom-elements.html ( diff )
/dom.html ( diff )
/index.html ( diff )
/infrastructure.html ( diff )