Open aleventhal opened 4 years ago
If the working group agrees with this change, I think we should probably update the text in https://w3c.github.io/aria/#tree_exclusion, which currently states:
If not already excluded from the accessibility tree per the above rules, user agents SHOULD NOT include the following elements in the accessibility tree:
- Elements, including their descendants, that have aria-hidden set to true. In other words, aria-hidden="true" on a parent overrides aria-hidden="false" on descendants.
Aside: If the working group does not agree with this change, we should probably update the text in https://w3c.github.io/aria/#tree_inclusion, which currently states:
If not already excluded from the accessibility tree per the rules above in Excluding Elements in the Accessibility Tree, user agents MUST provide an accessible object in the accessibility tree for DOM elements that meet any of the following criteria: [...]
- Elements that may fire an accessibility API event.
- Elements that are focusable, or have an ID attribute and an ancestor with the aria-activedescendant attribute that matches the implicit or explicit semantics of the required context role. In either case, the element may receive focus and may fire an accessibility API focus event.
My read of the current spec text is that because elements with aria-hidden='true'
SHOULD NOT be included, they are "already excluded from the accessibility tree" and thus we're never going to get to the user agents MUST related to firing events and being focusable.
Related aside: I believe the reason that is a SHOULD NOT is because Mozilla didn't want to make the change and thus would formally object to a MUST NOT. It isn't because we wanted to leave it up to user agents to introduce non-interoperable experiences. :wink:
Something we need to find out from screen reader developers on Windows is whether or not these things suddenly appearing in the accessibility tree will be a problem. (It shouldn't be in Linux because I never removed the for-Mozilla sanity checks from Orca. But I don't know what everyone in Windows did with their just-in-case code.)
Regarding Windows, JAWS is the one who has asked for this change. I've emailed NVDA to ask for an opinion. However, I know it's not an issue for 2 reasons. 1) This is how Firefox exposed things until relatively recently (they changed because some platforms like Mac didn't have a clear way of marking nodes invisible), 2) We already expose focusable aria-hidden nodes to them, which they ignore in their virtual buffer. We've been doing this for a few releases.
The aria-hidden attribute was created because there are good reasons to hide visible content from screen reader users. Making this change would more or less completely undermine the point of having it.
Does FS have quantifiable data in support of their proposal that they can share? A change like this would have serious consequences for screen reader users, so I think we'd want to be absolutely sure that the advantages to users outweigh the disadvantages before considering it.
Agree with @LJWatson - sometimes there are good reasons to hide things from AT.
I have used aria-hidden
to hide the guts of a decorative SVG. :)
I have also used it to hide funny characters in font icons.
If we made this change, I'm pretty sure that a bunch of redundant or extraneous content would suddenly show up where authors were counting on it staying aria-hidden.
Related to @joanie's comment, reminder that there are word changes for the inclusion/exclusion sections awaiting review in PR https://github.com/w3c/aria/pull/1100.
I plead to keep aria-hidden as it is. Too many exception rules (like for role=presentation) make it even more complicated to use ARIA correctly
@JAWS-test, screen reader behavior would not change, and this would not affect authoring practices. We are only providing a way to work around issues pages are authoring incorrectly. The issue is that aria-hidden is misused quite often and the screen reader has no chance to address it.
@LJWatson @carmacleod Screen reader behavior would not change. However, if a user contacts JAWS technical support because they cannot access something, JAWS would be able to provide steps to workaround the issue. Right now they cannot do any repair on these. Repair of bad content is something that needs to occasionally happen.
Sorry, what does that mean “repair something”?
Thinking out loud here.
If that means that they have a financial incentive to script around others’ bad accessibility implementations, then I have a problem with facilitating that or making that easier. That makes the web worse, not better, for anyone except the individual fortunate enough to have an employer who is willing to pay for this one-time fragile workaround.
If it means something else, let me know, but it’s the worst thing when something is inaccessible, and the short-term fix is directly antithetical to the long-term solution, which is the case here because pragmatically speaking, once that pain point goes away, then it will never ever be pursued.
If it means a feature whereby you can say “show hidden elements” for example, so that aria-hidden can be ignored by the screen reader to facilitate access, I would see why that could be attractive as a work around, but I feel very conflicted making it easier to get around inaccessible pages. Obviously, as a user, I want this functionality (I do), but as someone who wants there to exist external network pressures; social, financial, and legal, I’m just not so sure.
Thoughts?
@aleventhal
screen reader behavior would not change
However, I understood your initial comments to mean that the screen reader behavior changes:
JAWS recently asked us to consider exposing all visible aria-hidden objects
We currently expose focusable aria-hidden nodes. When the author misuses aria-hidden, the user can at least hear where they are tabbing to, instead of complete silence
These are changes to the screenreader output, because currently aria-hidden causes the content not to be output by the screenreader even if it gets the focus.
I am not against repair mechanisms in the screen reader. I am also in favour of not preventing them. But the repair mechanisms should not be defined in the specification:
A simple example:
For aria-hidden I can imagine the following:
@JAWS-test I think we agree then. We would still transmit the hidden status. The mechanism to render aria-hidden content would be via configuration. Otherwise, the current behavior is followed. Note: this would also be only for stuff that actually is visible to the sighted user.
As far as the focusable aria-hidden thing we're doing, this is for focus mode (as opposed to browse/virtual buffer mode). It doesn't make sense to say absolutely nothing if the user tabs and focus lands somewhere. If the focus lands somewhere that is aria-hidden, JAWS/NVDA etc. will try to read something useful, when used with Chrome, so that the user isn't completely lost. There were too many pages putting aria-hidden on the body element when a modal dialog was open. Sad.
@aleventhal commented:
Screen reader behavior would not change. However, if a user contacts JAWS technical support because they cannot access something, JAWS would be able to provide steps to workaround the issue. Right now they cannot do any repair on these. Repair of bad content is something that needs to occasionally happen.>
There is no guarantee that screen reader behaviour won't change. FS effectively pulled support for aria-controls last year, burying the toggle to enable support somewhere deep in Jaws' settings.
As I mentioned above I think we need some actual data for a decision like this. How often do authors get this wrong to the extent it damages the user experience? Is it significantly more often than they get it right?
@sinabahram commented:
If that means that they have a financial incentive to script around others’ bad accessibility implementations, then I have a problem with facilitating that or making that easier. That makes the web worse, not better, for anyone except the individual fortunate enough to have an employer who is willing to pay for this one-time fragile workaround.>
It does seem as though this is being requested to assist FS with its Jaws scripting services.
This isn't about scripting or consulting. Our intention for JAWS is to expose a user configurable option that says "Ignore ARIA Hidden on this page" that could be enabled on a per-page or per domain basis to allow users to function in the face of incorrect markup. We agree that aria-hidden provides a valuable role when used properly and we don't want to alter the default. But we do want to empower users to get things done when aria-hidden on pages would otherwise prevent it. As things stand, screen readers can't do any user directed remediation because aria-hidden content never makes it into the accessibility tree.
Here are a couple of cases where aria-hidden is improperly used. In both of them, the misuse is in third-party javascript libraries that the developers of the apps in question can not easily change. Aria-hidden is used on an iframe element that has an entire web application inside of it. This is for a call center environment. It's also misused to hide clickable icons in the Mavenlink project management tool. The icons are used for deleting things, expanding/collapsing items and manipulating calendar dates.
We're just trying to solve a technical problem. Sorry that I don't have numbers, but this came up twice in crbug.com in the last year, which is actually surprising given that we don't get very many external bugs filed. Glen mentioned separately to me that it comes up as a support issue. We don't really have a way a measuring "when someone gets it wrong", which is the same reason we wouldn't automate anything about it.
On the bigger picture, I didn't know we were still discussing as a community whether to enable users to make repairs. I think we have to be realistic about the fact that ARIA is one of the easiest technologies for authors to get wrong. There is so much expertise required to build a web app, and ARIA is only one small piece that a given developer needs to understand. Most authors aren't very comfortable with screen readers and not everything gets tested as much as it should. The spec is complex, and I still get things wrong about it myself. For example, it's really easy to break aria-hidden by assuming it works like CSS visibility -- that aria-hidden=false on a descendant undoes things aria-hidden on an ancestor. And when aria-hidden=true gets applied to the body, a sighted tester won't even notice. (Perhaps we should consider prohibiting aria-hidden on the top frame's body or html element, or perhaps we should allow aria-hidden=true on descendants to make that part of the tree visible, which would be helpful in the modal dialog case.
There have been arguments about whether it's right to enable repair of bad content, for example whether auto alt is a good idea. I think that because of the reality of how often accessibility is done incorrectly, and how hard it is for even developers who care to get it 100% correct, we should at least make repairs possible. Users have things to get done, and not all are in a position to go call up a company and wait for probably never to get a fix. We aren't successfully changing things by making users suffer more.
I asked a recent very knowledgable accessibility QA engineer, who didn't know my history of ARIA, for an honest assessment of how often ARIA makes a page better vs. worse. She said it makes it better about half the time, and worse about half the time. I don't know how to measure it, but I do know that if I'm a user trying to hold a job or get something done, I don't want to for developers to make an accessibility fix when they may be focused on something else, for whatever reason.
Apologies for the long spiel, but I don't think we should need to argue about enabling repair scenarios going forward. Maybe I'm just too forgiving of developers not getting accessibility right all the time! But it is definitely super easy to break accessibility with ARIA, by its very nature.
I don't think there's any doubt that aria-hidden is sometimes misused, any more than there is doubt that it's used properly too.
That's why we shouldn't base a decision like this on single examples. We should be absolutely sure that it's misused more often than it's not, and that when it's misused there are no alternatives to working around that.
Sorry, that was an accidental click. Not a statement, haha, although I do find this conversation a little frustrating :/
Hi @LJWatson I think I probably didn't explain the proposal well. In general, aria-hidden wouldn't change for users and authors The idea here is that when a user calls technical support because of missing content there is a configuration option for them.
For this idea, do you think we need to prove it's misused more often than used properly?
@aleventhal I am ok with this proposal now. I didn't fully understand it at first. It shifts the burden of implementing aria-hidden support from the user agents to the screen readers. As long as that's ok with the screen reader devs, then it's ok with me.
We have a way of marking nodes as invisible on every platform except Mac. Therefore, on Mac, we would likely fall back on simply not including the node, or at least not including it in children. The node would still be able to fire events and expose its ancestry chain.
We need to get @cookiecrook to weigh in on this.
You mentioned an email to NVDA in https://github.com/w3c/aria/issues/1185#issuecomment-579914477 but it would be nice to hear from @jcsteh in this issue.
@LJWatson I think I may be able to get some rudimentary data. I'll get back to you within the hour.
Also, as @joanie mentioned above, if the WG agrees with this change, we would need to make changes to the inclusion/exclusion sections of the spec. I would appreciate it if we started with the words in PR #1100.
It shifts the burden of implementing aria-hidden support from the user agents to the screen readers. As long as that's ok with the screen reader devs, then it's ok with me.
Yes, with the possible exception of platforms where this isn't implemented yet. JAWS/NVDA/Orca already hide objects exposed with an invisible state (although JAWS also needs the hidden object attribute). We should be able to safely do this without any noticeable change for users. There might actually be a net performance improvement as we currently spend a lot of computation power determine whether to expose something or not. Or it could make performance worse. Ultimately we need to try it to find out.
As much as I understand the real world implications here, I'm super reluctant to go down this path. For many years, Firefox didn't prune aria-hidden objects from the tree, precisely because of the concerns raised here. Part of the reason we ended up finally doing this after so many years was many complaints from authors and AT vendors that we weren't complying with the spec (despite our belief that we were doing the right thing for users), which caused friction because different implementations were doing different things. Despite the obvious issues, at least pruning aria-hidden trees was now clearly defined and consistent: if you use this badly, you get exactly the same result, regardless of browser and AT. Thus, a messy, years-long can of worms was finally closed. Now, we're talking about reopening this.
The problem is that it's not as simple as just saying "stop pruning the tree":
And probably other issues I haven't thought of yet...
@aleventhal, thanks for the detailed response, and sorry if you find the conversation frustrating. I think it's helpful, though, and I would like to humbly point out that just trying to solve a technical problem is how a lot of significant usability problems start, and most of the time, under the best of intentions. It's also abundantly obvious that this is one of those issues that engenders a strong response given past discussions, perhaps not all of which have been experienced by everyone, so your patients is appreciated.
I of course am very interested in and thankful for the issues that @jcsteh brings up.
@LJWatson I scanned 613 website home pages (I can scan more, but it would take a lot longer). The scan found 31 instances of aria-hidden. Data is pasted below. Note that for brevity I only printed the start tag of any element that contained aria-hidden. To see the full content of an element, please click on its URL and locate the element in its DOM.
Instances of aria-hidden: 1
Examples: [<div class="errmsg" aria-hidden="true" data-error-in-service-message="An unexpected error occurred, please try again.">]
Instances of aria-hidden: 11
Examples: [<h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <h3 class="spotlight-recirc__title" aria-hidden="true">, <svg width="85" aria-hidden="true" viewBox="0 0 73 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="mit-logo site-footer__logo">]
Instances of aria-hidden: 12
Examples: [<a class="nav-search-button" href="https://archive.org/search.php" onclick="$(this).parents('#nav-search').find('form').submit(); return false" aria-hidden="true" >, <span class="iconochive-search" aria-hidden="true">, <a href="https://archive.org/details/inlibrary?sort=-publicdate" style="background-image: url('https://archive.org/images/book-lend.png');" aria-hidden="true" data-event-click-tracking="TopNav|CircleWidget-BooksToBorrow" >, <a href="https://openlibrary.org" style="background-image: url('https://archive.org/images/widgetOL.png');" aria-hidden="true" data-event-click-tracking="TopNav|CircleWidget-OpenLibrary" >, <a href="https://archive.org/details/tv" style="background-image: url('https://archive.org/services/img/tv');" aria-hidden="true" data-event-click-tracking="ItemList|ItemListLink" >, <a href="https://archive.org/details/911" style="background-image: url('https://archive.org/services/img/911');" aria-hidden="true" data-event-click-tracking="ItemList|ItemListLink" >, <a href="https://archive.org/details/etree" style="background-image: url('https://archive.org/services/img/etree');" aria-hidden="true" data-event-click-tracking="ItemList|ItemListLink" >, <a href="https://archive.org/details/librivoxaudio" style="background-image: url('https://archive.org/services/img/librivoxaudio');" aria-hidden="true" data-event-click-tracking="ItemList|ItemListLink" >, <a href="https://archive.org/details/internetarcade" style="background-image: url('https://archive.org/services/img/internetarcade');" aria-hidden="true" data-event-click-tracking="ItemList|ItemListLink" >, <a href="https://archive.org/details/consolelivingroom" style="background-image: url('https://archive.org/services/img/consolelivingroom');" aria-hidden="true" data-event-click-tracking="ItemList|ItemListLink" >, <a href="https://archive.org/details/metropolitanmuseumofart-gallery" style="background-image: url('https://archive.org/services/img/metropolitanmuseumofart-gallery');" aria-hidden="true" data-event-click-tracking="ItemList|ItemListLink" >, <a href="https://archive.org/details/brooklynmuseum" style="background-image: url('https://archive.org/services/img/brooklynmuseum');" aria-hidden="true" data-event-click-tracking="ItemList|ItemListLink" >]
Instances of aria-hidden: 1
Examples: [<button type="button" class="close" data-dismiss="modal" aria-hidden="true">]
Instances of aria-hidden: 1
Examples: [<i class="uscb-header-search-icon o-search-1" aria-hidden="true">]
Instances of aria-hidden: 1
Examples: [<div id="buhp-navigation-modal" class="buhp-navigation-wrapper wp-prepress-component-modal is-style-full" aria-hidden="true">]
Instances of aria-hidden: 1
Examples: [<a href='#top' title='Scroll to top' id='scroll-top-link' aria-hidden='true' data-av_icon='' data-av_iconfont='entypo-fontello'>]
Instances of aria-hidden: 3
Examples: [<button class="clear_input" type="button" aria-hidden="true">, <span aria-hidden="true" class="ss-icon ss-delete">, <span aria-hidden="true" class="ss-icon ss-delete">]
In case it's interesting, here is the full list of web pages scanned. (697 were attempted, but due to errors or timeouts, only 613 could be scanned).
@LJWatson
In case it's useful, I let the scan run on 10000 home pages, and found 529 instances of aria-hidden
.
Here's a really quick surface analysis of some of the uses:
Here are a few oddities. I didn't look at any of these in situ (i.e. CSS/JS may fix them).
<noscript aria-hidden="true" role="presentation">
not quite sure what the point of this one is 🤔
<div class="svg-sprite-sheet sr-only" aria-hidden="true">
sr-only and aria-hidden seem a bit odd together (did the author want AT to see it or not?)
<nav class="offcanvas is-at-top-level" role="navigation" aria-label="Main Navigation" aria-hidden="true" id="MainMenu" aria-modal="true">
I'm guessing that the author was trying to hide offcanvas, tabindex=-1 nav links from AT by adding aria-hidden and aria-modal to the nav (which doesn't support aria-modal)
<a href="http://www.fnal.gov/pub/science/particle-physics/index.html" aria-hidden="true" role="presentation" tabindex="-1">
someone tried very hard to hide this link from AT, but didn't succeed (unless it's also hidden with CSS)
If anyone wants to do a deeper analysis of any of these 529 aria-hiddens, I've pasted the details below.
Unfortunately, aria-hidden often gets applied to something that shouldn’t be hidden (e.g. an
This isn't unprecedented. We currently expose focusable aria-hidden nodes. When the author misuses aria-hidden, the user can at least hear where they are tabbing to, instead of complete silence.
There would likely be benefits, at least in Chrome's in terms of simplifying the logic.
We have a way of marking nodes as invisible on every platform except Mac. Therefore, on Mac, we would likely fall back on simply not including the node, or at least not including it in children. The node would still be able to fire events and expose its ancestry chain.