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

Best practice - dialog / confirm-dialog: overly verbose accessible name/description #164

Closed
TetraLogicalHelpdesk opened this issue Mar 17, 2021 · 9 comments
Labels
a11y phase 3 Candidates for a 23.1 batch of a11y fixes a11y Accessibility issue help wanted Extra attention is needed needs research More information needed to estimate

Comments

@TetraLogicalHelpdesk
Copy link

Pages/screens/components affected

Description

In both the Dialog and the Confirm Dialog, the entire dialog overlay receives initial focus when the dialog is opened. While not necessarily a failure of WCAG, this does - depending on the specific browser/assistive technology used - lead to the content of the dialog itself being announced twice. For instance, in Chrome/NVDA, the Simple Dialog is announced as follows:

simple  dialog
clickable  This simple dialog will close by pressing the Esc key, or by a mouse click anywhere outside the dialog area
simple
This simple dialog will close by pressing the Esc key, or by a mouse click anywhere outside the   dialog area

While this is slightly redundant, it can become more problematic in the case of confirmation dialogs. Here, in addition to reading out all the content of the dialog, the action buttons for the dialog are explicitly set to also announce the dialog message, as they reference it using aria-describedby. As a result, assistive technology users may end up hearing the message of the dialog three times (twice when the dialog is opened, and once more when they reach the action buttons).

Example of a confirm dialog

See this video recording of the confirm dialog opening in Chrome with JAWS.

User impact

Overly verbose announcements can make it much harder for an assistive technology user to be able to understand the purpose of interactive controls, or to easily read/understand content.

Recommended solution

Review the suggested focus behaviour from the latest WAI-ARIA Authoring Practices 1.2 for modal dialogs (covered in the first "Note"; this has recently been changed - see the related GitHub issue and pull request).

For content dialogs, a suggested approach is to set focus on a content or placeholder element at the start of the dialog's content, rather than the entire dialog container itself. In the case of dialogs which primarily include a short message and action buttons, set focus to the first actionable element (and make sure the dialog container itself references the message using aria-describedby). See this simplified example:

<div role="dialog" aria-labelledby="dialogTitle" aria-describedby="dialogMessage">
  <h1 id="dialogTitle"> ... </h1>
  <div id="dialogMessage"> ... </div>
  <!-- set focus directly to this button -->
  <button>OK</button>
</div>

Implementation guidance

Currently, in the confirm dialogs, the action buttons include an explicit aria-describedby="..." attribute.

<vaadin-button id="confirm" aria-describedby="message" theme="primary" tabindex="0" role="button">OK</vaadin-button>

At a minimum, we recommend removing the aria-describedby, to avoid even further redundant announcements for assistive technology users when they interact with the dialog.

Test procedure(s)

Use these steps to confirm that the solution has been correctly applied to issues identified within the test sample, and to test the rest of the website for instances of the same issue:

  1. Turn on your screen reader
  2. Open a confirm dialog.
  3. Verify that contents of the dialog are not repeated multiple times.

Definition of done

Complete all of these tasks before closing this issue or indicating it is ready for retest:

  • All issues identified within the test sample have been resolved.
  • The rest of the components, their variants, and the documentation website have been tested for the same issue.
  • All issues identified throughout the rest of the components/website have been resolved or filed as new issues.

Related standards

More information

Test data

Test date: March 2021
Website: vaadin.com/components, vaadin.com/docs-beta

@web-padawan web-padawan added the a11y Accessibility issue label Mar 17, 2021
@web-padawan
Copy link
Member

The root cause for focus going to the overlay part is this vaadin/vaadin-overlay#69 and it was implemented in order to not focus first component automatically. See also some reasons here: vaadin/vaadin-overlay#68 (comment)

@knoobie
Copy link
Contributor

knoobie commented Mar 31, 2021

Additional remark: The discussion about focusing the dialog or the first element is a long long discussion in the whole industry. Even the browser vendors can't decide what they wanna do with the upcoming native dialog - Chrome and Firefox have different oppinions atm, if they wanna focus the dialog or not.

See the related discussion here https://bugzilla.mozilla.org/show_bug.cgi?id=1701230 and the provided Github Link to WHATWG.

@web-padawan web-padawan added the help wanted Extra attention is needed label Mar 31, 2021
@rolfsmeds
Copy link
Contributor

rolfsmeds commented Apr 13, 2021

I think the way ConfirmDialog buttons refer to the "message" element in their describedby attrib is also problematic as it skips the "header" part entirely, so any context there would presumably be unannounced?

Anyway, applying the ARIA guidance to our components, it seems to me that

  • Dialog, whose contents we cannot make any assumptions of, should put focus on an invisible "dummy" element at the top of it content structure.
  • ConfirmDialog, which in the vast majority of cases only contains a message and 1-3 buttons, should put focus on the "confirm" button. (While technically ConfirmDialog can contain anything as well, this is a rare use case and could be solved by documenting the need to explicitly set focus elsewhere if needed. We should also recommend to put focus on another button in case the "confirm" button is destructive.)

I presume in addition to this, the ConfirmDialog should have an aria-labelledby pointing at both the title and the message elements in order to announce both?

But what about regular Dialog – as it doesn't have a built-in title (yet), will it only be announced as "dialog", and then the user will need to traverse its contents to get the title etc read out?

@rolfsmeds
Copy link
Contributor

Also not sure how to reconcile this with the need for a scroll-container with tabindex="0" to make the dialog's contents scrollable with keyboard, as described in #127.

@knoobie
Copy link
Contributor

knoobie commented Apr 13, 2021

@rolfsmeds You can find here some additional example with different use cases you described above with or without description like e.g. normal dialog vs verification dialog for better usability (focus ok btn).

https://www.w3.org/TR/wai-aria-practices-1.2/examples/dialog-modal/dialog.html

See example 3 - initial focus is on the button, but the dialog should still announce the text thanks to "The element containing the dialog message is referenced by aria-describedby to hint to screen readers that it should be announced when the dialog opens."

@patrickhlauke
Copy link

I presume in addition to this, the ConfirmDialog should have an aria-labelledby pointing at both the title and the message elements in order to announce both?

In general, the idea (see https://w3c.github.io/aria-practices/#dialog_roles_states_props) is that on the element with role="dialog", the aria-labelledby points to the title of the dialog, and aria-describedby points to the element containing the message/description.

Once the dialog is opened, and focus is set to the first focusable element (for these types of functional/confirmation dialogs), the screen reader will announce that: the user is now in a dialog, what the title of the dialog is, what the description/message of the dialog is, and then continue on to describe the actual control that focus was set on.

But what about regular Dialog – as it doesn't have a built-in title (yet), will it only be announced as "dialog", and then the user will need to traverse its contents to get the title etc read out?

If a dialog doesn't have a title as such, it's fine to leave it out. IF the dialog is still conceptually more of a functional dialog (it shows an alert, choice, a form, or similar), focus can still go to the first focusable element, and if there is some text/message that precedes the choice controls/form, that can be tied to the role="dialog" element using aria-describedby - again, screen readers will then announced: the user is now in a dialog, what the message/description for the dialog is, and then describe the currently focused control.

If the dialog is more about showing/displaying structured content (e.g. it has a lot of content with headings, subheadings, lists, etc), then just having the whole of that content announced in one single "breath" by the screen reader as part of the aria-describedby is not ideal, as the structure etc will be difficult to process for users / may not be announced at all by screen readers. In these cases, the suggested approach is that of a dummy element or similar at the start of the dialog to receive initial focus. Screen reader users will simply hear that they've moved into a dialog, and then that's it, it's left up to them to explore it/read it/navigate it as normal.

Also not sure how to reconcile this with the need for a scroll-container with tabindex="0" to make the dialog's contents scrollable with keyboard, as described in #127.

To start with, if the scroll-container has any focusable child elements, then tabindex="0" is not stringently necessarily needed, as keyboard users will be able to tab/focus to the focusable child element, and once there, use cursor keys to scroll that container. However, it's still best practice to have the tabindex="0" there just in case / to provide a more consistent experience for keyboard users.

Taking the scrollable modal example from https://vaadin.com/components/dialog/html-examples one approach there could well be to set initial focus to the <header>Alice...</header> (and, as this leads to the header content being announced, not setting any aria-labelledby on the role="dialog", as otherwise there'd be a double announcement of the header - first, as part of the "you're now in a dialog, and this is the title of the dialog" screen reader behaviour, and then for the following "and this is the element you're now on"). Beyond that, I'd leave the rest of the behaviour at that, relying on screen reader user to just navigate through the content of that dialog on their own.

@rolfsmeds rolfsmeds added the a11y phase 3 Candidates for a 23.1 batch of a11y fixes label Dec 21, 2021
@rolfsmeds
Copy link
Contributor

Having a built-in header with a title element in the dialog would provide a natural place for setting default focus in a dialog that would also announce the title of the dialog automatically. See #1513

@rolfsmeds
Copy link
Contributor

Related: #4975

@rolfsmeds
Copy link
Contributor

As the Dialog implementation, and the remaining related issues, have changed quite a bit since this issue was created, I'm closing it in favor of #5709.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a11y phase 3 Candidates for a 23.1 batch of a11y fixes a11y Accessibility issue help wanted Extra attention is needed needs research More information needed to estimate
Projects
None yet
Development

No branches or pull requests

5 participants