Skip to content

Modal: neither focus nor tabbing are contained within #6579

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

Closed
3 tasks done
imageck opened this issue Apr 11, 2023 · 5 comments
Closed
3 tasks done

Modal: neither focus nor tabbing are contained within #6579

imageck opened this issue Apr 11, 2023 · 5 comments
Labels

Comments

@imageck
Copy link
Contributor

imageck commented Apr 11, 2023

Prerequisites

Describe the bug

Focus and tabbing can leave the modal despite enforceFocus={true}.

Expected behavior

Focus and tabbing should be limited to the modal.

To Reproduce

  1. Create a modal with a bunch of interactive elements in it.
  2. Open a modal.
  3. Keep tabbing until the focus is on the last element.
  4. The next tab will make the focus leave the modal altogether instead of wrapping.

Reproducible Example

Any example from the documentation, e.g. live demo.

Screenshots

No response

What operating system(s) are you seeing the problem on?

Linux

What browser(s) are you seeing the problem on?

Firefox

What version of React-Bootstrap are you using?

2.7.2

What version of Bootstrap are you using?

5.3.0-alpha3

Additional context

Unreproducible with vanilla Bootstrap. There the tabbing order works as expected and is contained within the modal.

@imageck imageck added the bug label Apr 11, 2023
@jquense
Copy link
Member

jquense commented Apr 12, 2023

Focus should wrap, keep hitting tab (unless you have it turned off with enforceFocus=false). Focus moves to the end of the modal then out of the window to the url bar and then back to the modal, this is how native dialogs work as well and an area that RB does better than most JS modals that trap focus in the window

@imageck
Copy link
Contributor Author

imageck commented Apr 12, 2023

But that's not how it works in vanilla Bootstrap, is it? WAI-ARIA also recommends containment of focus/tabbing:

The aria-modal attribute is used to indicate that the presence of a "modal" element precludes usage of other content on the page. For example, when a modal dialog is displayed, it is expected that the user's interaction is limited to the contents of the dialog, until the modal dialog loses focus or is no longer displayed.

In my specific scenario, the next tab moves the focus onto the last element (a link in the footer), and consequently, scrolls the backdrop all the way down. That's not a good experience in my opinion. Ideally, both focus and tabbing are contained within a dialog as described in the guidelines.

I want to make one thing clear: react-bootstrap is absolutely awesome and I wouldn't trade it for anything. However, that doesn't mean it's perfect and free of bugs or quirks. Sorry if that came across as mean. My intentions were never to compare it to other frameworks or even put it down.

@jquense
Copy link
Member

jquense commented Apr 12, 2023

Sorry, i'm not being defensive or upset just explaining that this is intentional and thought out. It differs from vanilla bootstrap because we believe that it's better to be closer to the correct behavior than to match upstream.

What the guidelines mean when they say "focus should be contained" is that a dialog should act as the entire document for the page, e.g. behave as if it was the only element rendered in the page. Normal document tab flow allows the focus to move out of the document to the browser UI when you reach the end, and then cycle back to the first element from the browser UI when you keep tabbing. This is the behavior we are trying to emulate and something that other JS modals fail to do correctly.

Notice that this is how the native dialog element works https://5qyc7e.csb.app/ as well which is the gold standard for correct accessibility. The one tradeoff tho we had to make to get this to work correctly is the scrolling issue sometimes happens which we would love to fix (and maybe we can) but overall we believe it's better to have the more correct a11y behavior if we need to pick.

@imageck
Copy link
Contributor Author

imageck commented Apr 24, 2023

The spec makes it clear that user interaction should not leak outside a modal. You could argue that the user should still be able to tab to the browser's UI (which is how the dialog element behaves) but leaving the rest of the page sequentially focusable doesn't make any sense. As I described before, it leads to page scrolls and a "jumpy" behavior.

APG is also unambiguous in this regard even if it's less authoritative to a degree.

At the moment, Modal is not quite on par with the dialog element. While it's open, the elements outside of it are tabable, which scrolls the main document.

@jquense
Copy link
Member

jquense commented Apr 24, 2023

Happy to accept PRs to address the case where focus jumps, just not at the expense of trapping focus inside the window permanently! From an a11y perspective we are happy with it's behavior and have verified it works well with experts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants