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

Screen reader read's selected value as 'blank' #1585

Open
ericj17 opened this issue Mar 3, 2017 · 15 comments
Open

Screen reader read's selected value as 'blank' #1585

ericj17 opened this issue Mar 3, 2017 · 15 comments
Labels
category/accessibility Issues or PRs related to accessibility issue/bug-confirmed Issues about a bug that has been confirmed by a maintainer

Comments

@ericj17
Copy link
Contributor

ericj17 commented Mar 3, 2017

Hi there,

I am noticing that a screen reader (NVDA and WIndows 10 Narrator) is unable to read the selected value in the react-select field. NVDA will read it as 'blank' (see screenshot below).

readblank

To reproduce using NVDA screen reader:

  1. tab to the react-select field
  2. the screen reader will read the combo box as having a value of 'blank' even though a value is selected

Any suggestions on how to rectify this so that screen readers can read the value selected in the react-select field?

Thanks and Regards,
Eric

@ericj17 ericj17 changed the title react-select Screen reader read's selected value as 'blank' Mar 3, 2017
@meditatingCybermind
Copy link

I also was looking into this issue and thought it was related to role="listbox" or role="combobox" not being assigned to the parents of the elements with role="option", but this did not solve the issue. NVDA reads out "blank" whenever it focuses on an empty line, though it will say "blank" even if searchable is false.

@IrinaBadiginaEpam
Copy link

What is the status of the issue?

@acromarco
Copy link

As a workaround I append the selected Option to the aria-label. The tricky part is, that now the screen reader (NVDA) will still read the old value when the user selects a new value. As solution to this problem, I don't append the selected Option to the aria-label while the select menu is open.

<ReactSelect
  aria-label={'My Label' + (this.state.isOpen ? ` Option ${selectedOptionLabel} is selected` : '')}
  onMenuOpen={() => this.setState({isOpen: true})}
  onMenuClose={() => this.setState({isOpen: false})}
  // ...
/>

I'm not sure whether this is a good solution, but at least the screen reader now get's information about the selected option.

@bladey bladey added the category/accessibility Issues or PRs related to accessibility label May 28, 2020
@bladey bladey added the issue/reviewed Issue has recently been reviewed (mid-2020) label Jun 17, 2020
@ebonow ebonow added awaiting-author-response Issues or PRs waiting for more information from the author and removed issue/reviewed Issue has recently been reviewed (mid-2020) labels Jan 18, 2021
@ebonow
Copy link
Collaborator

ebonow commented Jan 18, 2021

Greetings and apologies for the long delay in a response from the collaboration team.

I noticed that this is a screenshot from v1 and was wondering if this is still an issue for v2 or v3? I am uncertain what accessibility strategy was used at the time, but for now, aria-live is being used for a11y.

Based on the behavior, I would be apt to believe that the screenreader is reading "blank" because the input is cleared on blur. It would seem reasonable to perhaps set the aria-label onChange, onBlur, or perhaps even onFocus depending on timings.

I want us to be able to address accessibility in an intelligent way, and for now that focus is on aria-live for v3.3, but we will continue to look into ways to support WIA-ARIA following that to ensure that we are not introducing conflicts related to competing audio cues.

I will be marking this as awaiting-author-response to see if there is anyone that confirm that this is still an issue within the library or if this is simply expected behavior. I also am not sure what the status of this is versus aria-live, so please feel free to add any findings so we can appropriately handle this issue.

@ebonow ebonow mentioned this issue Feb 2, 2021
14 tasks
@ebonow
Copy link
Collaborator

ebonow commented Feb 5, 2021

As an update, I have spent a bit more time with the aria-live implementation. This is indeed an issue that I have documented and added as a to-do as part of all known aria-live issues in #4414

@ebonow ebonow added issue/bug-confirmed Issues about a bug that has been confirmed by a maintainer and removed awaiting-author-response Issues or PRs waiting for more information from the author labels Feb 5, 2021
@skippone
Copy link

skippone commented Feb 12, 2021

I've been investigating this issue (using the latest 4.1 version) and I believe the reason NVDA (and perhaps other readers too) reads "blank" is because the input field is focused all the time.

Once the menu is opened the input field should not yield focus, the menu should be focused instead. The accessibility of the menu, options and input field would also be greatly improved if the following aria attributes would be added together with the focus change:

<Input> component

  • role: "combobox"
  • "aria-autocomplete": "list"
  • "aria-expanded": menuIsOpen
  • "aria-owns": MENU_LIST_ELEMENT_ID

<MenuList> component

  • role: "listbox"
  • id: MENU_LIST_ELEMENT_ID

<Option> component

  • role: "option"
  • "aria-posinset": props.options.indexOf(props.data) + 1
  • "aria-selected": props.isFocused
  • "aria-setsize": props.options.length

There is quite a good post on the topic of accessible autocomplete at https://adamsilver.io/blog/building-an-accessible-autocomplete-control/.

I was trying to workaround the focus input issue using custom component but so far have not been successful.

@ebonow
Copy link
Collaborator

ebonow commented Feb 12, 2021

Thanks @skippone

Please correct me if I am wrong, but my experience with VoiceOver is that "blank" is read as the value, because the input is empty which is the built in accessibility support for autocomplete=list. Implementing this with aria-live, allows more flexibility as the control can read back instructions along with the currently selected value(s) - which is likely a behavior I will be looking into implementing into the PR this weekend.

I am working on a PR currently to shore up some of the loose ends regarding the aria-live implementation #4414 and then follow back around to the aria-roles so that we can understand where there might be conflicts to allow more granular control to allow users to turn one or the other off to avoid redundant information. This especially becomes important as adding more attributes adds potentially more "noise" (figuratively and literally).

Regarding focus control, I am not sure I understand this...

the input field should not yield focus, the menu should be focused instead

...though I interpret it to mean that the input should yield focus. Unfortunately, it's not an arbitrary task to say "give focus to the menu" as much of the internal functionality is tied to focus/blur methods on the input. This is not to say what is the correct approach but that it would require a larger rewrite to accomplish this.

Additionally, I would welcome any further testing of my PR branch especially by those with NVDA or JAWS.

Thank you much for the link, and will take some time to dig deeper into it when I get some time.

@bozdoz
Copy link

bozdoz commented Mar 11, 2021

I tested Material-UI's implementation of their Autocomplete component, to see if Windows/NVDA had the same issue: it does not. https://material-ui.com/components/autocomplete/

I would have guessed it would have a similar problem, seeing that there is an input field, and it remains "blank".

At first glance, it appears as though a significant difference could be that Material UI's component includes aria-controls and aria-activedescendant on the text input (which it should). I tried to get this to work with react-select before, but it was made somewhat difficult in my case because DummyInput is not customizable (if component does not have isSearchable={true}), and the Input should use this.state.focusedOption to get a value for active-descendant.

If you'd like I could draft a PR, which I imagine could fix this.

@ebonow
Copy link
Collaborator

ebonow commented Mar 11, 2021

@bozdoz Thank you much for doing the research on this. I'll bring this up on our weekly call tonight and get back to you on this. I think this would be a big win.

My concern with using the focusedOption is that it may not be focused especially in cases where the select is async or in most cases when data options are still being retrieved. Perhaps better is to use the SingleValue and MultiValue as the descendant element?

If this were the case, we'd likely want to address this in the accessibility section for custom Value components or when the user sets controlShouldRenderValue to false.

@mks1948
Copy link

mks1948 commented May 25, 2021

Hello,
My company supports accessibility and we use our package. We have a problem with NVDA+FIrefox. Yesterday I spent a lot of time to recognized. When I focus on the element, the screen reader reads 'options' and next 'blank' I think it's undesirable behavior.
The problem is even in the accessibility section on docs.

@sharan98727
Copy link

yaa i agree with mks1948, this problem exists on their docs too. screen reader is not reading the options.

@ebonow
Copy link
Collaborator

ebonow commented Jun 24, 2021

We have a developer dedicated to accessibility that will be digging into this more deeply. What has slowed this examination was the issues introduced in V4 by upgrading to Emotion 11 which did not play nice with apps built with components using Emotion 10 - which was the case for the platform Sean was using in his development environment.

Now with V5 going into beta (today - fingers crossed) we can begin to look into these accessibility issues more in depth.

@travisroth
Copy link

Hi,
A lot of good thoughts in the previous comments. Yes aria-activedescendant and aria-owns, etc., will fix the reading of "blank" instead of a selected value. It is not necessary to manipulate the focus in the list, it is just necessary to identify to the accessibility API using aria-activedescendant which one is selected. This is a huge accessibility and usability problem as the user does not know if her selection was accepted or what it now is.
Please consider using the ARIA 1.1 design pattern for comboboxes instead of these workarounds with live regions which is not a best practice. I recommend referring to this information in the W3C ARIA 1.1 Best Practices: https://www.w3.org/TR/wai-aria-practices-1.1/examples/combobox/aria1.1pattern/listbox-combo.html .
Thank you.

@gfohl
Copy link

gfohl commented Jan 13, 2022

I was able to fix this by using the MultiValueLabel component, passing in a unique id to innerProps, then adding that id to aria-labelledby in Select. Thie typings do not allow this prop, so if using TS you might need to extend the type.

const MultiValueLabel = ({ children, ...multiRest }) => (
    <components.MultiValueLabel {...multiRest} innerProps={{ id: unqiueId }}>
      {children}
    </components.MultiValueLabel>
  );
<Select aria-labelledby={uniqueId} components={{ MultiValueLabel }}/>

@bozdoz
Copy link

bozdoz commented Mar 22, 2024

@ebonow what is the current direction towards solving this issue? Is it decided that react-select should follow w3 recommendations? Are you committed instead to customizing live regions and making screenreaders more explicit? Are you open at the moment to accepting PR's for this matter? If so, what change would you expect?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category/accessibility Issues or PRs related to accessibility issue/bug-confirmed Issues about a bug that has been confirmed by a maintainer
Projects
None yet
Development

No branches or pull requests