Re: [csswg-drafts] For the Accessibility API visibility:visible within visibility:hidden is problematic (#6123)

> I don't feel like it is conceptually all that complicated. The real problem, in my mind, is that AT apparently treats

This isn't just AT. It's right throughout the entire stack: OS APIs, a11y specs, browsers, AT.

> `visibility: hidden` and `display: none` as though they mean the same thing, when they were never meant to be in CSS.

Maybe they're not the same in CSS, but CSS is also not primarily focused on semantics. So, a11y had to come up with a semantically appropriate mapping. That mapping has been this way for decades.

> But `visibility: hidden` isn't supposed to do that. It is only making that one element or pseudo-element (including its text nodes) completely transparent, without affecting descendant elements except through inheritance.

The fact that it is inherited is hugely relevant for a11y. That means an entire subtree could be "invisible" to sighted users. Sites in the wild (e.g. Google Help Panel) use visibility: hidden to hide entire sections of a page from sighted users.

> It still abides in the render tree, and should also still abide in the a11y tree. So, in my mind, the equivalent for screen readers is that it shouldn't be read aloud, but it should still maintain its meaning and structure and place in the tree.

But the a11y tree isn't the render tree. It does not have a concept of "an entire subtree which is in the tree but shouldn't be read". Furthermore, "shouldn't be read aloud" and "should still maintain its meaning" are incompatible concepts for a11y. If it has meaning, it should be read. Otherwise, it shouldn't be exposed. Again, this is how a11y works and has always worked. You can argue that's wrong, but unless we have a path to change an entire industry and stack, that's not a pragmatic argument.

> If the element had no visible descendants and no descendants that acted as labels or table headers, etc., then it could be treated the same as `display: none` or `aria-hidden="true"`, because only then is the element and its descendants both empty and meaningless.

And herein lies the problem. The proposal here requires that whenever a visibility: hidden element is encountered, browser a11y engines must do one of three things:

1. Crawl the entire subtree first to determine whether there is a visible descendant.
2. Skip hidden nodes as they do now, and then if a visible descendant is found, retrospectively add the ancestors they skipped.
3. Include all nodes in the tree and somehow filter them out before returning them to the a11y client.

To make things even more complicated, we also have to figure out how to handle mutations. If a visible descendant gets added or removed, we have to do the whole calculation again, potentially rebuilding or throwing away massive parts of the tree.

At least for Firefox (speaking as the tech lead for Firefox a11y), any of these solutions is a massive undertaking and involves significant risk of potentially catastrophic regressions. 

> Note: All of these should be identical to the same situations with `display: contents`, so the answers should be the same as for that (or are equally undefined currently...)

Perhaps visibility: hidden and display: contents are conceptually similar in terms of layout implementation, but they are very different semantically. display: contents is a very clear message: this is semantically relevant but not visually relevant. In contrast, visibility: hidden is often used to hide entire parts of a page visually, so it is not necessarily saying "this is semantically relevant". It depends on the subtree, which is where things get really nasty as outlined above.

-- 
GitHub Notification of comment by jcsteh
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/6123#issuecomment-918762792 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 14 September 2021 03:17:23 UTC