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

Fix combobox issues #1051

Merged
merged 17 commits into from
Nov 1, 2019
Merged

Fix combobox issues #1051

merged 17 commits into from
Nov 1, 2019

Conversation

mcking65
Copy link
Contributor

@mcking65 mcking65 commented Sep 11, 2019

The purpose of this pull request is to revise a collection of combobox issues by better aligning the specification with what has been long supported by both browsers and assistive technologies.

The rationale for these changes and an explanation of how they resolve the issues listed below are available on this wiki page about resolving ARIA 1.1 combobox issues.

Summary of changes in this pull request

  1. Revise definition of combobox to encompass implementations that do not support text editing, such as some implementations of the HTML select element by browsers.
  2. Revise description of the structure of combobox so the element with the combobox role is the focused element instead of a wrapper that is not focusable and the relationship with the popup is defined by aria-controls.
  3. Change the super class to input from select so it describes the actual structure; select is a composite and the revised combobox structure does not include any focusable descendants. This also has the beneficial side effect of removing aria-orientation, which is not applicable.
  4. Add aria-activedescendant as a supported property because it is no longer inherrited from its super class.
  5. Remove all required owned elements. A combobox no longer has any descendants.
  6. Change section 2.3 (id="managingfocus") to remove combobox from the list of composite widgets and for clarity and compatibility with revised combobox structure.
  7. Editorial revisions to the definition and description of the aria-activedescendant property to reflect the changes to the combobox structure.

Issues resolved by this pull request

Example Implementation

View an test an example implementation of the new pattern in the Authoring Practices Guide

Preview Changes

View the rendered changes in the compare branch for this pull request


Preview | Diff

@jhausler1266
Copy link

I wont be at TPAC, so i'll leave my comments here.

Changing combobox this way worries me, as Salesforce has already followed the 1.1 spec and created both design system guidelines and web components using this structure.

https://www.lightningdesignsystem.com/components/combobox/
https://developer.salesforce.com/docs/component-library/bundle/lightning:combobox/example

The 1.1 structure makes perfect sense as combobox is a combination of an input and a list, tree, grid, etc.

Also, in the case where we are mimicking an html we place readonly on the so that users cannot type. In this case the input is readonly, but the combobox is not, and therefore should communicate that it can take input.

Can we not move the AT vendors to move towards 1.1?

@accdc
Copy link
Contributor

accdc commented Sep 12, 2019

"Changing combobox this way worries me, as Salesforce has already followed the 1.1 spec and created both design system guidelines and web components using this structure."

This is what always worried me about this design pattern, and why I pushed for adding the criteria in the APG Read Me section saying that all web components need to be tested for sufficient accessibility support before adding them to production environments.

This is why I'm seeing so many inaccessible combobox implementations across public sites like GitHub and others, and yes Salesforce too, where it is extremely difficult to accessibly use them now, and this is harming accessibility everywhere as a result.

@jhausler1266
Copy link

I understand this perspective, but major accessibility auditing companies (Level Access included) often point to the APG when bugs are found during evaluations. We also regularly get customer feedback in the form of "bugs" citing our ARIA 1.0 components as inaccessible, with remediation guidance to move to 1.1.

For many, APG is the source of truth for accessible component development. For this reason, we've adopted an approach where we follow APG and wait for AT to catch up. If things are egregiously inaccessible, we'll make adjustments, but no one wants to support all the browser/AT and versions that exist.

Regarding Combobox specifically, we have found that our 1.1 comboboxes see much better support than our older 1.0 combos.

Copy link
Contributor

@eps1lon eps1lon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for putting the time into improving the combobox.

First time reviewing one of these so please forgive me if I made some false assumptions about the usability of these when using mouse pointers:

  1. When the listbox is open clicking outside the combobox won't close it but clicking inside the textfield will

  2. first click will open the listbox, second will close it but subsequent clicks will toogle to open state in rapid succession

  3. when to menu is opened mouseleave will only close if the listbox has been mouseentered. This is confusing if the listbox is opened by clicking the textfield and mouseleaving the widget will only close it after the listbox has been entered. I would suggest not closing the listbox after mouseleave. I find these behaviors very frustrating personally.
    combobox-leave-enter

  4. Hovering/clicking the label opens the listbox which is nice but can be confusing in this case since it covers the full line resulting in a noticeable invisible hitbox.

@accdc
Copy link
Contributor

accdc commented Sep 13, 2019

Thanks, it's true that Level Access points to the APG for general guidance, but not for the combobox widget. All of the reasons why are discussed in the following article, which I've instituted as a company policy for Level Access.
https://www.levelaccess.com/differences-aria-1-0-1-1-changes-rolecombobox/

If your 1.0 comboboxes were constructed using this criteria, they would not be inaccessible. These have been tested across all mainstream AT and browser combinations on all supporting platforms to ensure this.

index.html Outdated
</p>
<p>
Elements with the role <code>combobox</code> have an implicit <pref>aria-haspopup</pref> value of <code>listbox</code>.
If the <code>combobox</code> popup element has a role other than <rref>listbox</rref>, authors MUST specify a value for <pref>aria-haspopup</pref> that corresponds to the type of its popup.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change:

corresponds to the type of its popup.

to:

corresponds to the role of its popup.

(because it feels more precise)

index.html Outdated
&lt;ul role="listbox" id="owned_listbox"&gt;
&lt;li role="option"&gt;Zebra&lt;/li&gt;
&lt;li role="option" id="selected_option"&gt;Zoom&lt;/li&gt;
&lt;input type="text" aria-label="Tag"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example would be friendlier if it used a <label for="the-text-input">Tag</label> instead of an invisible aria-label="Tag". :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why not? As a sighted user, I prefer when a combobox has a visible label. I think we should model the most inclusive behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was supposed to be a thumbs up ... guess I somehow chose wrong emoji. Making the change.

index.html Outdated
The ARIA 1.0 specification describes a <code>combobox</code> pattern where the input element with the <code>combobox</code> role references the popup element with <pref>aria-owns</pref> instead of <pref>aria-controls</pref>.
<a>User agents</a>, <a>assistive technologies</a>, and conformance checkers SHOULD continue to support the ARIA 1.0 pattern so that existing implementations of the ARIA 1.0 pattern remain functional.
The ARIA 1.1 specification describes a <code>combobox</code> pattern where the element with role <code>combobox</code> is a composite container instead of a focusable input.
<a>User agents</a> and <a>assistive technologies</a> did not adequately support the ARIA 1.1 pattern, and this pattern supersedes the ARIA 1.1 pattern, which authors SHOULD abandon.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if "this pattern" is specific enough in the following phrase:

and this pattern supersedes the ARIA 1.1 pattern

Consider changing to:

so the ARIA 1.2 pattern supersedes the ARIA 1.1 pattern

@@ -2163,15 +2198,7 @@ <h2>Definition of Roles</h2>
</tr>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird typo in "Related Concepts:" row (was there before, but trivial to fix):

  • Delete /a> after [[HTML]]

index.html Show resolved Hide resolved
@carmacleod
Copy link
Contributor

Hi @eps1lon

Thanks for the good feedback on mouse behavior problems in the combobox example!

The current issue is about updating the ARIA combobox specification. The above Example Implementation was based off of an APG combobox example. Issues can be opened in the APG issue tracker.

I suspect that the mouse problems you are experiencing may exist in some of the other APG combobox examples as well.

@mcking65
Copy link
Contributor Author

@jhausler1266 commented:

The 1.1 structure makes perfect sense as combobox is a combination of an input and a list, tree, grid, etc.

I get this point totally ... there is a logiclal appeal to it. It is that logical appeal that convinced me to write the 1.1 structure into the spec even though I didn't really want to do so. 3 years later I am kicking myself for not pushing back harder, which would have probably meant we would have not made changes and stuck with 1.0 structure. maybe that would have been better than being in the position we are in now.

Also, in the case where we are mimicking an html we place readonly on the so that users cannot type. In this case the input is readonly, but the combobox is not, and therefore should communicate that it can take input.

I hoped 1.1 would help with this, but in reality there is no way that it can. Since the mid-90's, screen readers have presented the textbox as the combobox, not as something separate or as something inside the combobox.

Can we not move the AT vendors to move towards 1.1?

It is not impossible to get some of the bugs fixed. However, I don't think we will ever get screen readers to present the combobox as a composite widget -- never. I think the primary argument will always be that it will be really confusing for users because it has never been a true composite. It would also mean we have to also change how html:select@size=1 gets presented, which is also not proving straightforward.

On the other hand, changing a combobox from a composite to an input has pretty much 0 inertia on the screen reader side because it has always been presented that way.

@carmacleod
Copy link
Contributor

In case it's interesting, NVDA merged a PR 3 days ago to support ARIA 1.1 comboboxes in Chrome and FF. Not saying this changes anything. Just for info.

@mcking65 mcking65 marked this pull request as ready for review October 22, 2019 01:38
@mcking65
Copy link
Contributor Author

@jhausler1266,

With input from Microsoft and Freedom Scientific, I've been investigating and reviewing other ways of resolving the above listed issues. They get pretty complex. The changes in this pull request still seem to be the most straightforward.

Please read this wiki page:
https://github.com/w3c/aria/wiki/Resolving-ARIA-1.1-Combobox-Issues

<p>The <code>aria-autocomplete</code> property describes the type of interaction model a <rref>textbox</rref>, <rref>searchbox</rref>, or <rref>combobox</rref> employs when dynamically helping users complete text input. It distinguishes between two models: the inline model (<code>aria-autocomplete="inline"</code>) that presents a value completion prediction inside the text input and the list model (<code>aria-autocomplete="list"</code>) that presents a collection of possible values in a separate element that pops up adjacent to the text input. It is possible for an input to offer both models at the same time (<code>aria-autocomplete="both"</code>).</p>
<p>The <code>aria-autocomplete</code> property is limited to describing predictive behaviors of an input element. Authors SHOULD either omit specifying a value for <code>aria-autocomplete</code> or set <code>aria-autocomplete</code> to <code>none</code> if an input element provides one or more input proposals where none of the proposals are dependent on the specific input provided by the user. For instance, a combobox where the value of <code>aria-autocomplete</code> would be <code>none</code> is a search field that displays suggested values by listing the 5 most recently used search terms without any filtering of the list based on the user's input. Elements with a role that supports <code>aria-autocomplete</code> have a default value for <code>aria-autocomplete</code> of <code>none</code>.</p>
<p>When an inline suggestion is made as a user types in an input, suggested text for completing the value of the field dynamically appears in the field after the input cursor, and the suggested value is accepted as the value of the input if the user performs an action that causes focus to leave the field. When an element has <code>aria-autocomplete</code> set to <code>inline</code> or <code>both</code>, authors SHOULD ensure that the automatically suggested portion of the text is presented as selected text. This enables assistive technologies to distinguish between a user's input and the automatic suggestion and, in the event that the suggestion is not the desired value, enables the user to easily delete the suggestion or replace it by continuing to type.</p>
<p> If an element has <code>aria-autocomplete</code> set to <code>list</code> or <code>both</code>, authors MUST ensure both of the following conditions are met:</p>
<ol>
<li>The element has a value specified for <pref>aria-controls</pref> that refers to the element that contains the collection of suggested values.</li>
<li>Either the element or a containing element with role <rref>combobox</rref> has a value for <pref>aria-haspopup</pref> that matches the role of the element that contains the collection of suggested values.</li>
<li>The element has a value for <pref>aria-haspopup</pref> that matches the role of the element that contains the collection of suggested values.</li>
Copy link
Member

@jnurthen jnurthen Oct 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be changing this? While I get that we don't want people using the 1.1 combobox pattern this would make them invalid and I'm concerned about that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this an authoring requirement, not a browser requirement, making the 1.1 implementations invalid is helpful. The few existing implementations of 1.1, which already do not work well, will become invalid. That will promote fixing them so they work better for more users in more browsers. And, at the same time, nothing here changes browser behavior in a way that would make the existing implementations of 1.1 worse than they already are.

@JAWS-test
Copy link
Contributor

Unfortunately I do not understand the following explanation in the WIKI page

No select support: The input in the above code can be replaced with a div or span whose content displays the current value. This exactly replicates the functionality of combobox widgets that do not have a textbox.

If a div is used instead of input, no text can be entered. For AT users the difference is not noticeable, because in both cases the HTML element has the role combobox. So how should the difference between a combo box with text input and a combo box without text input be perceptible in the future?

@mcking65
Copy link
Contributor Author

Unfortunately I do not understand the following explanation in the WIKI page

No select support: The input in the above code can be replaced with a div or span whose content displays the current value. This exactly replicates the functionality of combobox widgets that do not have a textbox.

If a div is used instead of input, no text can be entered. For AT users the difference is not noticeable, because in both cases the HTML element has the role combobox. So how should the difference between a combo box with text input and a combo box without text input be perceptible in the future?

@JAWS-test wrote:

Unfortunately I do not understand the following explanation in the WIKI page

No select support: The input in the above code can be replaced with a div or span whose content displays the current value. This exactly replicates the functionality of combobox widgets that do not have a textbox.

This is a way to recreate the functional and accessibility equivalent of a select element with the size attribute set to 1. You cannot do this with the ARIA 1.1 pattern because there is no way for the AT to know which element contains the value.

If a div is used instead of input, no text can be entered. For AT users the difference is not noticeable, because in both cases the HTML element has the role combobox. So how should the difference between a combo box with text input and a combo box without text input be perceptible in the future?

Exactly the same way it is done today . Compare the experience of this combobox with a textbox implemented using the pattern in this PR with the experience of a select element with size set to 1 in either Chrome or Firefox on Windows. The combobox with a textbox has the editable text interface so a screen reader can announce it as an edit combobox. The select does not support editable text so it is announced as a combobox.

@JAWS-test
Copy link
Contributor

JAWS-test commented Nov 1, 2019

@mcking65 Thank you very much for your explanation. I assumed that when using an ARIA role, the screenreader always outputs the same role regardless of the HTML element used (ARIA roles override HTML semantics). I have tested the new example in Chrome with JAWS and it is indeed the case that at the input "edit combo" and at the span "combobox" is output, which surprises me very much. It's great that it works like this.

However, it might be necessary to update Core Accessibility API Mappings to reflect the different output depending on the HTML element.

The same applies to the following sentence in Using ARIA, which in my understanding would then also no longer be valid:

Adding an ARIA role overrides the native role semantics in the accessibility tree which is reported via the accessibility API, ....

And maybe also the ARIA specification:

When WAI-ARIA roles override host language semantics, ...

@JAWS-test
Copy link
Contributor

JAWS-test commented Nov 1, 2019

The new 1.2 combobox pattern is supported by JAWS and NVDA as follows:

  • NVDA and Chrome, Firefox and IE: combobox with and without text input is not output with different roles, but with different status ("changeable" for combobox with text input). In addition, the difference can be heard by the aria-autocomplete, if it is used for the combobox with text input
  • JAWS and Chrome: ok ("edit combo" or "combobox")
  • JAWS and Firefox: combobox with and without text input is not output with different role
  • JAWS and IE 11: wrong output because combobox and IE 11+JAWS never worked (none of the 1.0, 1.1 and 1.2 patterns, see role=combobox does not work FreedomScientific/standards-support#221)

However, in all browsers with JAWS and NVDA there is the problem that in the combobox without text input the value of the combobox cannot be output by the screenreader because it is not transmitted. This is a problem with the ARIA specification, which does not specify how a value is defined for the textbox and combobox roles (see #711):

<span tabindex=0 aria-label="label" role="combobox" aria-expanded="false" aria-controls="listbox">value</span>
<select id="listbox" hidden><option>1<option>2</select>

@JAWS-test
Copy link
Contributor

Actually I like the ARIA 1.2 combobox design. However, I think there are 2 problems:

  • combobox would be the only ARIA role that does not override the semantics of the host language, but enriches it. That would be a precedent that changes the previous role concept.
  • For this reason, the combobox role can't fully work in markup languages that don't have a native element with the textbox role (such as SVG, I believe) because the 1.2 design relies on the input field of the host language.

@jnurthen jnurthen merged commit d463bff into master Nov 1, 2019
jnurthen pushed a commit that referenced this pull request Nov 1, 2019
See https://github.com/w3c/aria/wiki/Resolving-ARIA-1.1-Combobox-Issues for full description of changes and motivations

* Revise description of user agent responsibilities for aria-activedescendant
* Remove combobox from list of composites for which authors must manage focus in section with id managingfocus_authors
* Revise prose of section managingfocus_authors to remove implications that the active descendant is always a DOM descendant of the element with DOM focus.
* Revise combobox example in aria-activedescendant definition so it does not describe textbox as contained by a combobox
* Add editor's note
* Revise aria-autocomplete description to match new combobox structure
* Add extra combobox warning
@mcking65
Copy link
Contributor Author

mcking65 commented Nov 7, 2019

@JAWS-test wrote:

Actually I like the ARIA 1.2 combobox design. However, I think there are 2 problems:

  • combobox would be the only ARIA role that does not override the semantics of the host language, but enriches it. That would be a precedent that changes the previous role concept.

It does override the role of the element just like every other ARIA role. Putting role combobox on an input:type=text overrides the textbox role.

Lots of ARIA roles effectively extend or enrich native semantics. The grid role can be used to extend or enrich table. The searchbox role can be used to extend or enrich textbox. I'd say it is the case for the majority of widget roles.

  • For this reason, the combobox role can't fully work in markup languages that don't have a native element with the textbox role (such as SVG, I believe) because the 1.2 design relies on the input field of the host language.

It would be a lot more work to make an editable combobox in any host language that does not have a text input that supports the accessible text interface. But, that was just as true for ARIA 1.1 and 1.0. And, it is just as true for creating an element with the searchbox role in one of those languages.

However, if you wanted to make a combobox that does not support editable text, it is now supported with ARIA 1.2. And, that is a big advantage if your host language does not have an element that supports the accessible text interface.

@mcking65
Copy link
Contributor Author

mcking65 commented Nov 7, 2019

@JAWS-test wrote:

@mcking65 Thank you very much for your explanation. I assumed that when using an ARIA role, the screenreader always outputs the same role regardless of the HTML element used (ARIA roles override HTML semantics). I have tested the new example in Chrome with JAWS and it is indeed the case that at the input "edit combo" and at the span "combobox" is output, which surprises me very much. It's great that it works like this.

However, it might be necessary to update Core Accessibility API Mappings to reflect the different output depending on the HTML element.

The same applies to the following sentence in Using ARIA, which in my understanding would then also no longer be valid:

Adding an ARIA role overrides the native role semantics in the accessibility tree which is reported via the accessibility API, ....

And maybe also the ARIA specification:

When WAI-ARIA roles override host language semantics, ...

I don't think we need those updates. It is up to the assistive technology to decide how they want to present the availability of editable text. It doesn't have to be part of the role announcement.

Of course, we always have the option of doing something in ARIA to specify what AT should do when the input is editable. I'd rather let AT attempt to solve this without specific direction from the ARIA specification. I think there is plenty of history that shows they will because it has been done in native applications. Apple's native approach is distinctly different from Microsoft's, and I don't see a reason to force them to be the same.

@JAWS-test
Copy link
Contributor

JAWS-test commented Nov 7, 2019

@mcking65

It does override the role of the element just like every other ARIA role. Putting role combobox on an input:type=text overrides the textbox role.
Lots of ARIA roles effectively extend or enrich native semantics. The grid role can be used to extend or enrich table. The searchbox role can be used to extend or enrich textbox. I'd say it is the case for the majority of widget roles.

As far as I have understood, each ARIA role overrides the HTML element. I can use role=grid (with all necessary child roles like row and gridcell) on a span or table element and it makes no difference which HTML element I use.

With role=combobox this would be different according to the new specification:

  • at an input field it would be an element like the HTML input with datalist
  • at a span element it would be an element like the HTML select.

These are two different elements with different operation modes, but with the same ARIA role combobox (see w3c/html-aam#230).

@jnurthen jnurthen deleted the fix-combobox branch November 7, 2019 23:59
@mcking65
Copy link
Contributor Author

@JAWS-test wrote:

As far as I have understood, each ARIA role overrides the HTML element. I can use role=grid (with all necessary child roles like row and gridcell) on a span or table element and it makes no difference which HTML element I use.

With role=combobox this would be different according to the new specification:

  • at an input field it would be an element like the HTML input with datalist

Not quite, but pretty close.

  • at a span element it would be an element like the HTML select.

Correct if size=1 and the operating system is Windows or Linux.

These are two different elements with different operation modes, but with the same ARIA role combobox (see w3c/html-aam#230).

Whether the element with role combobox is an HTML input or a span, the ARIA role overrides the implicit semantics and makes the element into a combobox. This is identical to other ARIA roles.

The interactions conferred by the combobox role are identical regardless of whether the input is editable. The combobox role communicates that the input controls a popup and the value of the input can be set via the popup.

And, like other ARIA roles, ARIA properties are used to add additional information about the interactions supported for a particular combobox, e.g., aria-haspopup and aria-autocomplete. This is like the button role. If you add aria-haspopup or aria-pressed, it adds additional information about supported interactions for the widget. Similarly, aria-haspopup adds interaction information to the menuitem role and aria-multiselectable adds interaction information to widgets with a variety of roles.

@JAWS-test
Copy link
Contributor

Whether the element with role combobox is an HTML input or a span, the ARIA role overrides the implicit semantics and makes the element into a combobox. This is identical to other ARIA roles.

I don't think I get it yet. Because role=combobox at the input element leads to the output of "edit combobox" in the screenreader and role=combobox at the span element leads to the output of "combobox". Those seem to be two different roles to me. In my opinion these are relatively different elements with different operation.

carmacleod pushed a commit that referenced this pull request May 7, 2020
See https://github.com/w3c/aria/wiki/Resolving-ARIA-1.1-Combobox-Issues for full description of changes and motivations

* Revise description of user agent responsibilities for aria-activedescendant
* Remove combobox from list of composites for which authors must manage focus in section with id managingfocus_authors
* Revise prose of section managingfocus_authors to remove implications that the active descendant is always a DOM descendant of the element with DOM focus.
* Revise combobox example in aria-activedescendant definition so it does not describe textbox as contained by a combobox
* Add editor's note
* Revise aria-autocomplete description to match new combobox structure
* Add extra combobox warning
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

Successfully merging this pull request may close these issues.

7 participants