question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Concerned about Dropdown Menu's modal accessibility

See original GitHub issue

Bug report

By default, Dropdown Menu uses a modal mode (modal=true), which prevents keyboard and/or screen-reader users from ever accessing content outside <DropdownMenuContent> without first selecting a <DropdownMenuItem>.

You state that you adhere to the Menu Button WAI-ARIA design pattern, however, this pattern never mentions that a user should be trapped within the dropdown, and indeed, their examples freely let users not interact with an open dropdown should they wish.

FWIW, setting modal={false} on your Codesandbox demo also seems to have no effect either, but I could be doing something wrong…

Current Behavior

  1. A keyboard user tabs on to the button
  2. They press Enter or Space to open the menu
  3. They decide they don’t want to interact with it
  4. They can’t (shift) tab out of it to other content on the page, nor to the <DropdownMenuTrigger> to close it again with Enter or Space (unless they press Escape)

The same goes for screen reader users who navigate with their previous and next commands. They are also trapped within the dropdown.

Expected behavior

Dropdowns are non-modal and are allowed to be ignored when opened. Users should be free to access content before or after it without closing it, or to be able to reach the <DropdownMenuTrigger> to close it, just as mouse users can.

Reproducible example

Your CodeSandbox Demo

Suggested solution

Remove the modal implementation and remove the <DropdownMenuContent> from being within a portal so a keyboard user’s (shift) tab key and a screen reader user’s previous and next commands actually take them to the relevant previous and next elements in the page.

I understand that not using a portal may present other issues (such as being clipped by overflow or z-index), however, I don’t know of any other way to maintain the document order for screen-reader users using previous and next (tab can be hacked around).

Additional context

The Menu WAI-ARIA pattern explicitly states:

Tab: Moves focus to the next element in the tab sequence, and if the item that had focus is not in a menubar, closes its menu and all open parent menu containers. Shift + Tab: Moves focus to the previous element in the tab sequence, and if the item that had focus is not in a menubar, closes its menu and all open parent menu containers.

Your environment

Software Name(s) Version
Radix Package(s) @radix-ui/react-dropdown-menu 0.1.0
React n/a 17.0.2
Browser Chrome 93.0.4577.82
Assistive tech VoiceOver
Operating System Mac

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
jjenzzcommented, Oct 21, 2021

Accidentally stumbled across some things that will help us solve this. Created a PoC here for when we’re ready to pick this up https://github.com/radix-ui/primitives/compare/popover-no-loop...non-modal-a11y

5reactions
stowballcommented, Sep 17, 2021

Thanks for the prompt reply. It’s good to see that with a combination of modal={false} and portalled={false} that you can get the dropdown much closer to spec. I would strongly encourage you to make this the default, or at a minimum call it out clearly in the docs.

When it comes to wai aria specs, one thing you may know already is that they are far from complete. Additionally, their examples also often are far from complete, or sometimes even wrong.

While I agree that some of the more complex components and pattern specs aren’t 100% perfect, the accessibility community is pretty much agreed upon the keyboard behaviour of such a rudimentary component like Menu Button. Here are a few examples I quickly found which all contain the correct tab behaviour (and some even explictly mention it):

You can see here that we explicitly prevent default on tab for that reason “for now”: https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L577

Ah, so that’s why I thought modal={false} wasn’t doing anything.

We may decide to at least focus back the trigger when pressing Tab from the Menu as a better temporary solution.

At a bare minimum this needs to be implemented, but I would strongly encourage full Tab support, especially when combining modal={false} and portalled={false}

Read more comments on GitHub >

github_iconTop Results From Across the Web

Building Accessible Menu Systems - Smashing Magazine
Dropdowns which constitute a set of options are often called "menus", and I want to talk about these here. We shall be devising...
Read more >
Fly-out Menus | Web Accessibility Initiative (WAI) - W3C
Use fly-out (or drop-down) menus to provide an overview of a web site's page hierarchy. It removes the need for multiple page loads...
Read more >
Dropdown design: guidelines for web and mobile - Justinmind
One of the main concerns when designing dropdown menus is the size and number of options. What makes a dropdown menu too big?...
Read more >
Stop Using 'Drop-down' - Adrian Roselli
It does not conform to the ARIA Menu pattern (as described above). It has no roles, so it is not exposed to screen...
Read more >
Carousels, Dropdowns, & Modal Dialogs: Accessibility and ...
Choices and Tradeoffs · With role="menu", links are treated as menu items, not links. But screen readers support role="menu" pretty well. · Without...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found