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(select): use combobox pattern for accessibility #20082

Merged
merged 1 commit into from
Aug 25, 2020

Conversation

crisbeto
Copy link
Member

@crisbeto crisbeto commented Jul 24, 2020

Applies some of our recent learnings on how to handle the accessibility of a custom select to mat-select. Includes switching the trigger to be a combobox and the panel to a listbox.

Fixes #11083.

@crisbeto crisbeto added P2 The issue is important to a large percentage of users, with a workaround Accessibility This issue is related to accessibility (a11y) target: patch This PR is targeted for the next patch release labels Jul 24, 2020
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jul 24, 2020
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

LGTM

src/material/select/select.ts Show resolved Hide resolved
@jelbourn jelbourn added lgtm action: merge The PR is ready for merge by the caretaker labels Jul 25, 2020
@crisbeto crisbeto force-pushed the select-a11y-fixup branch 2 times, most recently from b2c347a to 8669172 Compare July 26, 2020 08:09
@jelbourn jelbourn added the presubmit failures This PR has failures in Google's internal presubmit process and cannot be immediately merged label Jul 27, 2020
@jelbourn
Copy link
Member

So this has ~100 failing targets in Google from about 20 projects. I haven't looked too deeply, but it seems like a lot of people wrote selectors in their tests like mat-select[aria-label="..."]. I might see seeing about fixing up some of these with a harness and seeing how it goes.

@crisbeto
Copy link
Member Author

crisbeto commented Jul 28, 2020

Something to keep in mind about those selectors: people were probably trying to target a select with a specific placeholder. The select currently in master forwards its placeholder value to aria-label, unless aria-label is explicitly overwritten.

@mmalerba mmalerba removed the lgtm label Jul 31, 2020
@andrewseguin
Copy link
Contributor

Can we do the same thing as input and temporarily put that information into another attribute, then switch tests over to it? E.g. data-label

@crisbeto
Copy link
Member Author

crisbeto commented Aug 4, 2020

Have we confirmed that it's due to the selector? If that's the case, it's easy to add a similar attribute.

@andrewseguin
Copy link
Contributor

I'm seeing violations that the role=combobox doesn't contain a textbox child.

https://dequeuniversity.com/rules/axe/3.5/aria-required-children?application=axeAPI

Does that apply here? Is this check incorrect in this case?

@andrewseguin
Copy link
Contributor

Another set of failing accessibility errors gave me this:

Errors:
Error: AX_ARIA_04 (ARIA state and property values must be valid) failed on the following elements (1 - 4 of 4):
#mat-select-0
#mat-select-2
#mat-select-4
#mat-select-6
See https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_04 for more information.

Error: AX_ARIA_02 (ARIA attributes which refer to other elements by ID should refer to elements which exist in the DOM) failed on the following elements (1 - 4 of 4):
#mat-select-0
#mat-select-2
#mat-select-4
#mat-select-6
See https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_02 for more information.

@jelbourn
Copy link
Member

jelbourn commented Aug 11, 2020

The second one we should be able to fix in the PR, I think.

For the first one, the check is kind of problematic itself because we're following the draft ARIA 1.2 guidance on this. While this isn't the official ARIA spec today, it actually works better in most screen-readers than the active 1.1 spec.

@andrewseguin
Copy link
Contributor

If it works better, we can disable the check, open an issue internally, and link to it with a TODO?

@crisbeto
Copy link
Member Author

I've pushed a fix for the second error, but we can't do much about the first one.

@andrewseguin
Copy link
Contributor

Here's a fun use case that causes an ExpressionChangedAfterChecked - a mat-select with a placeholder, inside an ng-container with ngIf

crisbeto#15

@andrewseguin
Copy link
Contributor

I think three failures came up for accessibility:

  1. role=combobox doesn't contain a textbox child
  2. ARIA state and property values must be valid
  3. ARIA attributes which refer to other elements by ID should refer to elements which exist in the DOM

(1) should be handled by disabling the check since the test's ax check is just out of date for now
(2) is still giving errors
(3) seems to be gone

Is there anything we can do about (2)?

@crisbeto
Copy link
Member Author

Does it say which elements 2 and 3 are failing on? I pushed some changes last week that should've removed references to elements that aren't in the DOM yet.

Applies some of our recent learnings on how to handle the accessibility of a custom select to `mat-select`. Includes switching the trigger to be a `combobox` and the panel to a `listbox`.

Fixes angular#11083.
@crisbeto
Copy link
Member Author

Updated to fix the issue with aria-haspopup and the "changed after checked" error.

@andrewseguin andrewseguin added target: minor This PR is targeted for the next minor release and removed presubmit failures This PR has failures in Google's internal presubmit process and cannot be immediately merged target: patch This PR is targeted for the next patch release labels Aug 24, 2020
@andrewseguin andrewseguin merged commit 6fbf142 into angular:master Aug 25, 2020
annieyw pushed a commit to annieyw/components that referenced this pull request Aug 31, 2020
Applies some of our recent learnings on how to handle the accessibility of a custom select to `mat-select`. Includes switching the trigger to be a `combobox` and the panel to a `listbox`.

Fixes angular#11083.
@drc-nloftsgard
Copy link

I am seeing a critical violation 'Certain ARIA roles must contain particular children' (https://dequeuniversity.com/rules/axe/3.5/aria-required-children?application=AxeChrome) on https://material.angular.io/components/select/overview when analyzing with Axe Core. I thought this PR was intended to fix that issue?

@crisbeto
Copy link
Member Author

crisbeto commented Sep 3, 2020

If I remember correctly, the only error right now is that the combobox doesn't contain an input, but I believe that's permitted by a newer version of the ARIA spec. Before we made these changes, we spent some time testing different prototypes against all of the popular screen readers and consulting with some of Google's accessibility experts.

@jelbourn
Copy link
Member

jelbourn commented Sep 3, 2020

Yeah, we're a little ahead of axe here. See dequelabs/axe-core#2505

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Oct 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Accessibility This issue is related to accessibility (a11y) action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement P2 The issue is important to a large percentage of users, with a workaround target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MatSelect accessibility rework
6 participants