w3c / aria

Accessible Rich Internet Applications (WAI-ARIA)
https://w3c.github.io/aria/
Other
641 stars 124 forks source link

aria-hidden error case: disallow aria-hidden on root or document element (e.g. <html> or <body>) #1254

Open cookiecrook opened 4 years ago

cookiecrook commented 4 years ago

aria-hidden error case: disallow aria-hidden on root or document element (e.g. <html> or <body>)

The WG discussed a variety of author error cases we should formalize to provide a better end-user experience for assistive technology users.

The first anti-pattern we see frequently is authors adding aria-hidden="true" to the <html> or <body> elements. The call attendees agreed this should be universally disallowed. Suggestion was to ignore aria-hidden completely on these elements (and the equivalent elements in other host languages, like <svg>).

As I understand it, source HTML including <body aria-hidden="true"> in source HTML would be ignored by the UA, and not reflected in the DOM. Also the following would be no-op statements or throw warnings. These should potentially trigger console messages, too. Suggestion was to use console.log(), but I think console.warn() might be appropriate, too.

document.body.ariaHidden = true; // no-op [and warn] b/c on body element document.body.setAttribute('aria-hidden', 'true'); // no-op [and warn] b/c on body element

[Update 17 June 2021: See discussion and related issues linked below. If we proceed, aria-hidden on body should not be ignored in all cases.. It should only be ignored if the hidden state results in no remaining accessible content in the page.]

[Update 22 March 2023: element reflection should not affected (difficult or impossible IDL) be so the previously proposed (now stricken) no-ops should map to the accessibility internals and APIs only... e.g. UAs MUST NOT expose…]

cookiecrook commented 4 years ago

A more ambiguous variant is that aria-hidden could be ignored if doing so resulted in no rendered page contents. It wasn’t immediately clear if this was as achievable, or which heurisitics should be used, but an example would be:

<body>
  <div class="pagecontents" aria-hidden="true">contents hidden from assistive technology</div>
</body>

I think this could be spun out as a separate issue if necessary.

scottaohara commented 4 years ago

agree on your second comment being spun out as separate to this, since that method is often used as an important technique in properly hiding all content of the primary document when a modal dialog is invoked (e.g., what the the inert polyfill presently does while also tabindex=-1ing all the focusable elements within the "inert" element.

with this issue, does #1190 have any other elements that need an aria-hidden ban?

carmacleod commented 4 years ago

Suggestion was to ignore aria-hidden completely on these elements (and the equivalent elements in other host languages, like <svg>).

I don't think we want to ignore aria-hidden on <svg>. Authors often want to hide decorative or redundant inline svg content from screen readers. Case in point, inspecting the DOM of this github issue page, there are at least a dozen uses of aria-hidden="true" on decorative/redundant svg's in buttons, links, tabitems, etc. I think that should continue to be a valid use case.

JAWS-test commented 4 years ago

I wouldn't ban aria-hidden on the body. It can be used e.g. for iframes which are only used for tracking purposes. Alternatively, it should be noted that aria-hidden should be used on the iframe element itself

aleventhal commented 4 years ago

To answer @carmacleod and @JAWS-test, the proposal was actually to ban on the root element of the top/root document only. Therefore this would only be in situations where the author was hiding everything. Hiding on <svg> or for frames/iframes would therefore not be an issue.

However, I do want to put in one caveat. The group also discussed enabling aria-hidden=false, because authors naturally think that it should work, and it has been seen in the wild. If we do that, then we should not implement the rule in this issue.

@asurkov do you have an opinion?

aleventhal commented 4 years ago

I don't think we should do this if we implement the proposal in issue 1256, where we add support for aria-hidden=false, because a valid use case would be to put aria-hidden=true on the html/body, and aria-hidden=false on a descendant.

sinabahram commented 4 years ago

Wow, I feel super silly! I should have noticed this logical conflict on the call.

Hmm, I agree and think we need to just kill this one. If we do, then the error case of body with aria-hidden=”true” is still fixed because we said once anything with aria-hidden=”false” gets focus, we recurse up the tree invalidating or simply removing the aria-hidden of all parents.

I want to echo @accdc’s concern around that strategy of basing it on focus does not help VO users on iOS, a huge percentage of blind users of the mobile web, but that’s because body with aria-hidden=”true” for some reason prevents VO focus, so if @cookiecrook can get that behavior changed, then implementing #1256 would also address iOS users favorably too.

vicfei-ms commented 4 years ago

Chime in from Microsoft here. supportive of disallowing aria-hidden on root or document element as it aligns with them not being focusable.

sinabahram commented 4 years ago

@jcsteh since you mentioned this in another issue as part of some things that could help mitigate the problems we're trying to solve, may we assume you are good with this specific issue being implemented as described?

jcsteh commented 4 years ago

Overall, I'm okay with this, but I do have some questions/concerns:

  1. It's been noted that this part would be spun out into a separate issue, but for clarity, I have major concerns about the variant where aria-hidden could be ignored if doing so resulted in no rendered page contents. So, my "okay" here is conditional on that being excluded here.
  2. I worry about confusion/debugging pain with regard to disallowing aria-hidden on the top level document but allowing it on iframe documents. An author might not understand why some thing they're embedding works fine at top level but fails in an iframe. That said, that does bring up the problem with SVG.
  3. One implementation concern with all of these proposals is whether there is prior art for browsers removing/no-opping certain attributes and whether this violates any other spec. I'm not aware of any case where a browser no-ops setAttribute calls, but perhaps there are cases I'm unaware of? This is something I'd want to run by some Firefox DOM people. Historically, ARIA attributes have been handled entirely within the browser a11y engine and haven't had any impact on DOM. This would change that convention. @AnneVK, do you have any thoughts on this?
annevk commented 4 years ago

I hope that setAttribute() would continue to set the attribute and that no-op/ignoring refers to the processing model. Because yeah, setAttribute() should continue to set the attribute. (As should the HTML parser if you feed it <body aria-hidden>.)

If you want the ariaHidden IDL attribute to be special for these elements you can no longer rely on HTML's reflection algorithm and will instead have to define a special algorithm for that property that does the right thing on getting (and perhaps on setting, if you don't want to do anything there).

cc @domenic

ariellalgilmore commented 1 year ago

Taking a look at this issue and discussing with @spectranaut:

Maybe starting with a "authors must not" statement around using aria-hidden on html or body elements could be a good first step.

The last comment also mentions we can't disallow doing something like document.querySelector("html").ariaHidden = "true";, which makes me lean more towards using a authors must not statement

annevk commented 1 year ago

To be clear, I'm not saying you can't. I'm saying it would be more involved.

cookiecrook commented 1 year ago

@annevk wrote:

I hope that setAttribute() would continue to set the attribute and that no-op/ignoring refers to the processing model. Because yeah, setAttribute() should continue to set the attribute. (As should the HTML parser if you feed it .)

I think it's fine to leave setAttribute and reflection working as-is. The outcome would be two normative requirements:

  1. Authors MUST NOT use this... (Can be caught by validation tools, but does not prevent any DOM changes or reflection)
  2. UAs MUST NOT expose this... (e.g. aria-hidden on these nodes would have no affect in the platform mappings.)

If we ever expose a WPT/WebDriver property like computedVisibility, it could return the "correct" value.

cookiecrook commented 1 year ago

@carmacleod (❤️😢) wrote:

I don't think we want to ignore aria-hidden on <svg>.

I agree in reference to inline SVG in HTML. As I understand it though, inline SVG in HTML is not the root or document node, so aria-hidden would still be allowed there.

However, if the SVG is rendered directly outside of the HTML context (*.svg in the browser location field), aria-hidden="true" would result in no contents rendered, so it should be disallowed there, where it is the root node.

scottaohara commented 1 year ago

@cookiecrook per the way UA should be handled here, should the update be here in ARIA as well as ARIA in HTML (for author/conformance checker rule). Or should this be noted in the AAMs for ignoring aria-hidden=true when used on <html> and <body>, for example?

cookiecrook commented 1 year ago

Open to suggestions, or if you're itching to write it, okay to take assignment. I want to make sure this would also apply to window-rendered documents (SVG, etc) that were not embedded in HTML, but I think it's fine to have additional mention of this elsewhere. The more spec locations though, the more chance for mismatch.

scottaohara commented 1 year ago

agreed on the worry about potential mismatch.

and apparently since i was itching, i have created the draft and cc'd you in it so you can review/revise anything you think I didn't write well :)