angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.32k stars 6.73k forks source link

bug(MatSelect): MatSelect in a CdkOverlay panel is not accessible to screen readers #28709

Open wildcardalice opened 6 months ago

wildcardalice commented 6 months ago

Is this a regression?

The previous version in which this bug was not present was

No response

Description

Using a screenreader to interact with a MatSelect dropdown inside an overlay panel prevents it from reading out the options

Reproduction

StackBlitz link: https://stackblitz.com/edit/bqqfav-gaxbdf Steps to reproduce:

  1. Active VoiceOver or other screen reader
  2. Using a keyboard, click on the 'Launch dialog' button
  3. Using a keyboard, navigate to the select and attempt to read the options
image

Expected Behavior

VoiceOver should read out the options, much like it does when interacting with the examples at https://material.angular.io/components/select/examples

Actual Behavior

VoiceOver does not read out the options. It only reads "expanded, completion selected". Pressing ctrl+option+space causes it to read "confirm Favorite pet, list box pop-up, Menu popup combobox".

Environment

zarend commented 6 months ago

Hello,

Thank you for reporting accessibility issues. I can reproduce.

This appears to be a VoiceOver compatibility problem with aria-modal, but there is a work-around. By default, MatDialog with be an aria-modal with aria-modal="true". We set aria-modal to false using MatDialogConfig.

    this.dialog.open(DialogElementsExampleDialog, {
      ariaModal: false, // work-around VoiceOver compatibility issue with modal dialog (#28709)
    });

Stackblitz reproduction of work-around: https://stackblitz.com/edit/bqqfav-lnchne

Here's a bit more technical background of the problem.

What seems to happen is that VoiceOver isolates the content inside an aria-modal – that's all the DOM inside element with aria-modal="true". VoiceOver only has access to the modal and cannot see anything outside the modal. Overlay renders inside a <cdk-overlay-container/>, which is at the bottom of the DOM. it is not a child of MatDialog element. This causes compatibility issues with VoiceOver appeared to isolate Overlays from the content of the AriaModal. It caused the same behavior reported in this bug report and affected anything that uses Overlay, which is Angular component's popup system.

We worked around using aria-owns to creating a relationship in the DOM. That seemed to work for a little bit. Unfortunately, that work-around does not seem to work anymore. VoiceOver has known compatibility issues with aria-owns.

Assigning to myself with P2 priority.

Best Regards,

Zach