vaadin / web-components

A set of high-quality standards based web components for enterprise web applications. Part of Vaadin 20+
https://vaadin.com/docs/latest/components
447 stars 83 forks source link

context-menu: Modal-like small-screen menu does not contain focus nor hide underlying page from assistive technologies #99

Open TetraLogicalHelpdesk opened 3 years ago

TetraLogicalHelpdesk commented 3 years ago

WCAG Level

Level A

Priority

High

Pages/screens/components affected

Description

On smaller screens/viewports, the context menu component behaves like a modal dialog - when triggered, the underlying page is obscured with a semi-transparent overlay, and clicking/tapping anywhere outside of the menu closes it again. However, keyboard focus is not retained inside of this modal dialog - using Tab / Shift+Tab a keyboard user is able to navigate back out of the menu and into the underlying page, effectively navigating behind the open context menu. This can also lead to situations where focus is partially or fully hidden (no visible focus indication) if the focused element is positioned underneath the open menu.

Example of an open small-screen context menu, but with focus behind the menu and the semi-transparent overlay

Beyond keyboard focus, when the modal-like menu is open, the underlying page (which is visually obscured) is still navigable and readable using assistive technologies. Screen reader users can still use reading keys (or any other content navigation shortcuts) to navigate through the underlying page.

User impact

If screen readers are not restricted to reading the contents of a dialog, users can easily get lost by navigating into content that is not supposed to be available. Likewise, keyboard users will be confused by their focus landing underneath the semi-transparent overlay, or even disappearing completely to an element that is covered by the open drawer.

Required solution

Make sure that content underneath open dialogs is hidden from all users, including keyboard and assistive technology users.

This solution must be applied to all instances of the issue identified within the test sample, then applied to all other instances of the same issue identified throughout the rest of the components, their variants, and the documentation website.

Implementation guidance

When a modal dialog is displayed, content "behind" the dialog should also be hidden from assistive technologies, to avoid that users navigate back into the underlying main document (using the virtual/reading cursor, navigation by headings, etc).

At a high level, this can be achieved by adding aria-hidden="true" to the underlying page - making sure that the modal dialog itself sits outside of the hidden container, as otherwise it would also be hidden.

<body>
  <div aria-hidden="true">
    <!-- page content not in modal dialog -->
  </div>
  <div role="dialog" class="visible">
    <!-- dialog content -->
  </div>
</body>

An additional approach, which unfortunately is only partially supported in current user agent/assistive technology combinations, is to explicitly denote the modal dialog container as a modal dialog, adding both role="dialog" and the aria-modal="true" attributes. As this approach is not fully supported yet, we recommend still using the above aria-hidden approach.

This will take care of assistive technologies, but you will still need to implement focus handling for non-AT keyboard users - either by making all focusable elements in the underlying page non-focusable by adding tabindex="-1", or by implementing some other form of focus trapping/cycling that ensures that keyboard focus remains inside the drawer.

For a solid implementation of an accessible custom dialog, see A11y 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 components, their variants, and the documentation website for instances of the same issue:

  1. Turn on your screen reader.
  2. Make sure the browser viewport is small enough to trigger the "modal-like" behaviour of the component.
  3. Navigate to, and trigger, the modal.
  4. Verify that focus was placed into the modal.
  5. Verify that moving focus using Tab / Shift+Tab it is not possible to navigate out of the modal and into the underlying page.
  6. Verify that using reading keys (cursor keys) or other screen reader shortcuts (such as heading navigation) it is not possible to navigate out of the modal and into the underlying page.

Definition of done

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

Related standards

More information

Test data

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

rolfsmeds commented 2 years ago

Test if issue is still present in latest version. If so, something must be wrong with the focus trap logic.

christophe-g commented 10 months ago

Test if issue is still present in latest version.

Point 4. of the test does not work (Verify that focus was placed into the modal.). This is a problem for users interacting with keyboard only (context-menu is not visible nor operable with screen readers).

Workaround is to manually set the focus to the first item of the context menu, but this should be handled by the component itself.

The focus should also revert back to the element that had focus prior to opening the context menu - it is not included in the above test.

I am currently using v24.1.0.