- From: Steve Faulkner <faulkner.steve@gmail.com>
- Date: Thu, 28 Aug 2014 10:26:48 +0100
- To: "W3C WAI Protocols & Formats" <public-pfwg@w3.org>
- Message-ID: <CA+ri+V=5-1MG09pxyV13Ah38eYF4as3jBHqCk9PL347w96btvg@mail.gmail.com>
Forwarding some comments I sent web apps -- Regards SteveF HTML 5.1 <http://www.w3.org/html/wg/drafts/html/master/> ---------- Forwarded message ---------- From: Steve Faulkner <faulkner.steve@gmail.com> Date: 28 August 2014 10:24 Subject: Re: [Custom] Custom elements and ARIA To: Domenic Denicola <domenic@domenicdenicola.com> Cc: public-webapps <public-webapps@w3.org> hi domenic, a few quick initial comments, (I have only skimmed the material you have provided): I don't think it is currently possible to define the browser accessibility API mappings in terms of ARIA as it defines and incomplete set of roles,states and properties used in acc APIs. It appears (please correct me) you have made the assumption that 'strong native semantics' for roles is a UA requirement? This is not the case (in the W3C HTML spec [1] at least, can't speak for where the WHATWG spec has gone in defining ARIA in HTML), they are author conformance requirements. Section 3.2.7 WAI-ARIA [1] states: "User agents must implement ARIA semantics on all HTML elements, as defined in the ARIA specifications." Relevant to this is section 5.2. Conflicts between native markup semantics and WAI-ARIA [3] in the Core Accessibility API Mappings specification This is reflected in implementations, for example <hr role="menuitem"> is exposed in Chrome (in IAccessible2) on windows as; ROLE_SYSTEM_MENUITEM display:block tag:hr xml-roles:menuitem location=(8, 8) size=(1125, 2) index_in_parent=0 n_relations=0 n_characters=0 caret_offset=0 n_selections=0 The HTML spec (any brand) does not define how HTML features map to platform accessibility APIs. This is being normatively defined in the HTML Accessibility API Mappings specification [2]. Would it be worth considering exposing the platform accessibility APIs <http://rawgit.com/w3c/aria/master/implementation/aria-implementation.html#intro_aapi> used in the browser, to JS so that custom elements can be implemented to fully reflect native element accessibility implementations? [1] http://www.w3.org/html/wg/drafts/html/master/dom.html#wai-aria [2] http://rawgit.com/w3c/aria/master/html-aam/html-aam.html [3] http://rawgit.com/w3c/aria/master/implementation/aria-implementation.html#mapping_conflicts -- Regards SteveF HTML 5.1 <http://www.w3.org/html/wg/drafts/html/master/> On 28 August 2014 00:42, Domenic Denicola <domenic@domenicdenicola.com> wrote: > TL;DR: we (Google) are trying to explain the platform with custom elements > [1], and noticed they can't do ARIA as well as native elements. We would > like to prototype a solution, ideally as a standardized API that we can let > authors use too. (If that doesn't work, then we can instead add a > non-web-exposed API that we can use inside Chrome, but that would be a > shame.) A succinct statement of the problem is that we need some way to > explain [3]. The rest of this mail explains the problem in great depth in > the hopes other people are interested in designing a solution with me. > > Also, in the course of figuring all this out, I put together an intro to > the relevant aspects of ARIA, which you might find useful, at [2]. > > ## The problem > > Right now, custom elements can manually add ARIA roles and stoperties (= > states or properties) to themselves, by setting attributes on themselves. > In practice, this kind of allows them to have default ARIA roles and > stoperties, but they are fragile and exposed in a way that is incongruous > with the capabilities of native elements in this regard. > > For example, if we were to implement `<hr>` as a custom element, we would > attempt to give it the separator role by doing `this.setAttribute("role", > "separator")` in the `createdCallback`. However, if the author then did > `document.querySelector("custom-hr").setAttribute("role", "menuitem")`, > assistive technology would reflect our `<custom-hr>` as a menu item, and > not as a separator. So **unlike native elements, custom elements cannot > have non-overridable semantics**. > > Furthermore, even if the author wasn't overriding the role attribute, > there would still be a difference between `<hr>` and `<custom-hr>`. Namely, > `document.querySelector("hr").getAttribute("role") === null`, whereas > `document.querySelector("custom-hr").getAttribute("role") === "separator"`. > So **unlike native elements, custom elements cannot have default ARIA roles > or stoperties without them being reflected in the DOM**. > > As another example, imagine trying to implement `<button>` as a custom > element. To enforce the restriction to a role of either `button` or > `menuitem`, the custom element implementation would need to use its > `attributeChangedCallback` to revert changes that go outside those > possibilities. And that of course only occurs at the end of the microtask, > so in the meantime screen-readers are giving their users bad information. > And even then, the experience of the attribute value being reverted for the > custom element is not the same as that for a native element, where the > attribute value stays the same but the true ARIA role as reflected to > screenreaders remains `button`. So: **unlike native elements, custom > elements cannot robustly restrict their ARIA roles to certain values**. > > Finally, consider how `<details>` synchronizes `aria-expanded` with the > `open` attribute. To implement this with custom elements, you would use the > `attributeChangedCallback` to set an `aria-expanded` attribute. But again, > the author could change it via `setAttribute`, causing it to be > out-of-sync. The takeaway here is that **unlike native elements, custom > elements cannot reserve the management of certain stoperties for > themselves**. > > In the end, trying to manage one's ARIA state HTML attributes is fragile, > and lacks the conceptual stratification and the resultant power of the > internal state/mutable HTML attribute approach used by native elements. [3] > illustrates more drastically the differences between the internal state and > the HTML elements in many representative cases. > > ## Discussion > > In my own musings, I came up with a few solutions [4], but they are pretty > icky to program against. There are a few tough issues that emerge, e.g. > > - Do we allow programmatic changing of *all* elements roles/stoperties, > e.g. via a new API `element.aria.role = "whatever"`, or do we want some > kind of model that reserves that power for the author of the element code? > The former allows bad things like a <hr> with role menuitem, but the latter > makes for tricky programming. > > - If an element wants to manage some aspect of its ARIA state itself, e.g. > restrict its role, how does that impact the rest of its ARIA stuff? E.g., > how can I signal that I want to manage aria-expanded, ignoring any > attribute-setting that goes on, while at the same time allowing the author > to mess with aria-hidden at will? Or even more complex, how can I signal > that I want to have a default way of calculating aria-level, but if the > author sets it, their value overrides it (until they removeAttribute)? > > - Trying for a declarative solution, e.g. `"aria-expanded": function () { > return this.hasAttribute("open"); }` gets you 90% of the way there, but you > need some way of triggering an "ARIA recalc." E.g. <details> would trigger > an ARIA recalc when its open="" attribute changes, and h1 would trigger an > ARIA recalc whenever its position within the document changes (because that > potentially affects outline level), and input would trigger an ARIA recalc > under any situation where a <datalist> could become associated with it. If > you accept this premise, then who has the power to trigger an ARIA recalc? > Who has the responsibility? > > I would welcome anyone else's ideas on solutions. The cases that need to > be addressed are summed up, somewhat representatively, in [3]. If nobody is > interested I'll probably just evolve my existing kinda-icky solutions, and > code one of them into Chrome as a non-web-exposed API (or maybe expose it > behind a flag). > > [1]: https://github.com/dglazkov/html-as-custom-elements > [2]: https://gist.github.com/domenic/ae2331ee72b3847ce7f5 > [3]: https://gist.github.com/domenic/bc8a36d9608d65bd7fa9 > [4]: https://gist.github.com/domenic/4ddde9bdcb673c48f237 >
Received on Thursday, 28 August 2014 09:27:55 UTC