Skip to content
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

aria-controls should only point to visible elements #531

Closed
ZoeBijl opened this issue Feb 17, 2017 · 13 comments
Closed

aria-controls should only point to visible elements #531

ZoeBijl opened this issue Feb 17, 2017 · 13 comments

Comments

@ZoeBijl
Copy link

ZoeBijl commented Feb 17, 2017

There is currently nothing in the spec[1] that prevents aria-controls from pointing to something that is hidden. Léonie said on Twitter:

If aria-controls points to something not in the DOM, how do you navigate to it?

Should aria-controls therefore be limited to elements that are visible?

[1] ARIA 1.1 specification

@mcking65
Copy link
Contributor

@LJWatson, @MichielBijl,

First of all, hidden elements are in the DOM. They may not be in the AX tree in some APIs, but they are definitely in the DOM and idrefs to hidden elements are valid.

For good reason, aria-owns, aria-describedby, aria-labelledby, and aria-controls can all reference hidden elements. It would be unreasonable to expect web authors to syncronize the presence or values of these attributes with the visibility of the element being referenced.

To address @LJWatson's concern, you could either place some additional requirements on the browser regarding what is in the AX tree for aria-controls. Or, or you could very reasonably expect assistive technology developers to avoid providing a function that attempts to helpp users read something they cannot perceive.

I vote for NO CHANGE on this.

@LJWatson
Copy link
Contributor

What is the purpose of aria-controls pointing to something that can't be navigated to?

The attribute is intended to establish a relationship between two things. Those things may be far apart in the DOM, so it is logical that an implementation of aria-controls in a screen reader would provide a way to navigate from the control to the controlled element (as the only known screen reader implementation in fact does). If it is not possible to navigate to the controlled element, this breaks the user interaction completely.

I don't think it's unreasonable for developers to sync aria-controls with the visibility of the controlled element. This simple demo does it in a single line of JavaScript.

@AmeliaBR
Copy link
Contributor

Regarding @LJWatson's question:

What is the purpose of aria-controls pointing to something that can't be navigated to?

The specific use case from @MichielBijl's tab example (which would also exist in many other widgets) is that the controlling relationship is about revealing/hiding the linked content.

How would you expect that to be indicated, if aria-controls can't point to the element until after it is revealed? I'm assuming that the expanded/collapsed state or toggle button state is indicated by other aria properties. Would it make sense to add aria-controls to a toggle button, switch, or tab only after it has been activated?

The only structure that I could see that makes sense is if aria-controls pointed to a parent container element for the content that will actually be shown or hidden when the control is activated. But that could be a lot of extra markup for a simple accordion-style show/hide details structure.

@mcking65
Copy link
Contributor

@LJWatson commented:

What is the purpose of aria-controls pointing to something that can't be navigated to?

I am not sure that the primary purpose is assistive technology navigation; it is expressing the relationship for the benefit of forming an accessibility tree. If assistive technologies wish to piggy-back a navigation function on to the relationship, they can certainly do so. However, they should use common sense when doing so.

For example, the relationship between a listbox controlled by a text field that has aria-autocomplete="list" is established via aria-controls. This relationship is important to establish when building the accessibility tree.

@LJWatson commented:

it is logical that an implementation of aria-controls in a screen reader would provide a way to navigate from the control to the controlled element (as the only known screen reader implementation in fact does).

If it is not possible to navigate to the controlled element, this breaks the user interaction completely.

Agree. So, it is not logical for an assistive technology to suggest that you can navigate to a hidden element. The fact that one assistive technology has chosen to do so is somewhat bizarre. I think it is just a screen reader bug stemming from a simple oversight.

I don't think it's unreasonable for developers to sync aria-controls with the visibility of the controlled element.

It is more authoring work with literally no useful purpose. In isolation, and in simple cases, it is certainly trivial. But, it does not live in isolation and it is not always so trivial. Every unnecesary authoring complexity is another nudge in the direction of making accessibility more difficult and expensive.

Removing the relationship also removes information that can be useful when doing static analysis of code to verify correct implementation.

@klown
Copy link
Contributor

klown commented Feb 17, 2017

An element's visibility and presence in the DOM are not synonymous.

Something can be in the DOM and not be visible, as @mcking65 noted. A relevant case is the listbox associated with a combobox. It's not visible until the user makes a gesture to pop it open. This is a relevant case since aria-controls points from the combobox to the listbox, even when the listbox is not displayed (hidden). That's fine since aria-controls references an element in the DOM. Thus, aria-controls should not be limited to elements that are visible.

On the other hand, it's an author error when aria-controls references a non-existent element. That's something that a validator or QA should catch and the author should fix. If the error is not fixed, there is no graceful recovery. You simply can't navigate to something that doesn't exist. Compare this to when an author provides a link via an ID that doesn't reference any element in the DOM, e.g., <a href="invalidID" ... > If a user clicks that link, they go nowhere. It's implicit in the concept of "ID reference" that it be valid. There is no problem with the ARIA spec in this regard; nothing needs to be changed.

@LJWatson's demo hides the controlled object by not adding it to the DOM. Furthermore, the aria-controls attribute is not added until the controlled element is added to the DOM. The script synchronizes the presence of aria-controls and the controlled element. That's fine too.

The possibilities are:

  • The controlled element is in the DOM but is hidden. Adding aria-controls to the controlling element is valid.
  • The controlled element is not in the DOM. Wait until it is before adding aria-controls to the controlling element; that is, synchronize the presence/absence of the two.
  • The controlled element is not in the DOM but there is an aria-controls attribute on the controlling element. This is an author error that should be fixed.

@ZoeBijl
Copy link
Author

ZoeBijl commented Feb 17, 2017

It seems that this is heading in a “don’t change a thing” direction. For what it’s worth, @LJWatson and I did discuss aria-controls when it points to a hidden element that is in the DOM. While that doesn’t make any sense for AT navigation, it might for the forming of an accessibility tree as @mcking65 said.

I did made two examples of the tabs widget during dinner where aria-controls follows aria-select which you can view (separate branch):

Tabs With Automatic Activation (roaming aria-controls)
Tabs With Manual Activation (roaming aria-controls)

Note: these will be removed once this issue is closed.

@klown
Copy link
Contributor

klown commented Feb 17, 2017

I wrote:

  • The controlled element is not in the DOM but there is an aria-controls attribute on the controlling element. This is an author error that should be fixed.

Addendum: even if an author does not fix the error, browsers will not expose the controller-for/controlled-by relationship in the accessibility tree, because, well, there is nothing to expose. In constructing the accessibility tree, the browser will attempt to follow the (bogus) aria-controls reference, but will find nothing and will give up. The result is that there is no controller-for pointer in the accessible object. The end result is as if no aria-controls was present in the DOM. In particular, there is no pointer that could mislead a screen reader.

@mcking65
Copy link
Contributor

mcking65 commented Aug 3, 2018

@asurkov, @aleventhal, @minorninth, @cookiecrook, @melanierichards,

Would it be reasonable to add a browser requirement to expose aria-controls in the accessibility tree only when the referenced element is visible?

@StommePoes
Copy link

I am not sure that the primary purpose is assistive technology navigation; it is expressing the relationship for the benefit of forming an accessibility tree.

If there's a tree in the forest but nobody can perceive it, does it exist?

At my work we were mulling around what possible use aria-controls could have and other than as a handy JavaScript hook for developers, we concluded we could find zero use for it. We no longer write recommended code using it. It seems the whole point of creating a relationship between things is so that relationship is perceived. By something. If that's the browser, does the browser do anything with that information? Is this a case of "well someday in the future in a galaxy far far away something might do something useful with this"?

When newly-revealed stuff turns out to be far away from a control, some kind of navigation system sounds sensible. But it sounds like that's not even this thing's purpose in life.

@LJWatson
Copy link
Contributor

LJWatson commented Aug 6, 2018

@Stommpoes:

At my work we were mulling around what possible use aria-controls could have and other than as a handy JavaScript hook for developers, we concluded we could find zero use for it. We no longer write recommended code using it. It seems the whole point of creating a relationship between things is so that relationship is perceived. By something. If that's the browser, does the browser do anything with that information? Is this a case of "well someday in the future in a galaxy far far away something might do something useful with this"?>

aria-controls is exposed in all the accessibility API AFAIK. More to the point, it is supported (by way of an announcement and an optional navigational hotkey) by Jaws, which is (according to the last WebAIM survey) the primary screen reader of 46% and commonly used screen reader of 66% of people.

@jnurthen
Copy link
Member

Closing this and moving aria-controls discussion to #995

@adcortes
Copy link

adcortes commented Dec 5, 2022

An element's visibility and presence in the DOM are not synonymous.

Something can be in the DOM and not be visible, as @mcking65 noted. A relevant case is the listbox associated with a combobox. It's not visible until the user makes a gesture to pop it open. This is a relevant case since aria-controls points from the combobox to the listbox, even when the listbox is not displayed (hidden). That's fine since aria-controls references an element in the DOM. Thus, aria-controls should not be limited to elements that are visible.

On the other hand, it's an author error when aria-controls references a non-existent element. That's something that a validator or QA should catch and the author should fix. If the error is not fixed, there is no graceful recovery. You simply can't navigate to something that doesn't exist. Compare this to when an author provides a link via an ID that doesn't reference any element in the DOM, e.g., <a href="invalidID" ... > If a user clicks that link, they go nowhere. It's implicit in the concept of "ID reference" that it be valid. There is no problem with the ARIA spec in this regard; nothing needs to be changed.

@LJWatson's demo hides the controlled object by not adding it to the DOM. Furthermore, the aria-controls attribute is not added until the controlled element is added to the DOM. The script synchronizes the presence of aria-controls and the controlled element. That's fine too.

The possibilities are:

  • The controlled element is in the DOM but is hidden. Adding aria-controls to the controlling element is valid.
  • The controlled element is not in the DOM. Wait until it is before adding aria-controls to the controlling element; that is, synchronize the presence/absence of the two.
  • The controlled element is not in the DOM but there is an aria-controls attribute on the controlling element. This is an author error that should be fixed.

Implementing the second possibility, that seems very reasonable specially using angular ngIf conditional to show/hide listbox, it is still getting error as some tools as Siteimprove chrome plugin says that is like an missing or invalid aria-controls to the role=combobox element.

  • Removing aria-controls and just show it on click (when listbox appears in DOM) detects a missing aria-controls error
  • Leaving aria-controls without value, adding value on click detects an aria-controls invalid error

@JAWS-test
Copy link
Contributor

@adcortes According to https://www.w3.org/WAI/standards-guidelines/act/rules/5c01ea/proposed/#passed-example-7 aria-controls without value is the right solution. I'm not sure that's true. The document is currently under review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants