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

Allow modal dialogs to trap focus, avoiding tabbing to the URL bar #8339

Closed
koddsson opened this issue Sep 30, 2022 · 10 comments
Closed

Allow modal dialogs to trap focus, avoiding tabbing to the URL bar #8339

koddsson opened this issue Sep 30, 2022 · 10 comments
Labels
a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. needs implementer interest Moving the issue forward requires implementers to express interest normative change topic: dialog The <dialog> element.

Comments

@koddsson
Copy link

Hello!

We'd like to make a change to the spec to make sure that user agents focus trap the user with in a HTMLDialog.prototype.showModal() in order to be more closely aligned with WCAG2.1:

A modal dialog box

A Web application brings up a dialog box. At the bottom of the dialog are two buttons, Cancel and OK. When the dialog has been opened, focus is trapped within the dialog; tabbing from the last control in the dialog takes focus to the first control in the dialog. The dialog is dismissed by activating the Cancel button or the OK button.

Some comments from a previous discussion in https://crbug.com/1363100:

@koddsson & @keithamus

What steps will reproduce the problem?
(1) Navigate to https://yari-demos.prod.mdn.mozit.cloud/en-US/docs/Web/HTML/Element/dialog/_sample_.advanced_example.html.
(2) Open the dialog with the only button on the page.
(3) Tab through the elements in the dialog.

What is the expected result?

The user focus is trapped like described in https://www.w3.org/WAI/ARIA/apg/example-index/dialog-modal/dialog.html

Key - Function
Tab - When focus is on the last focusable element in the dialog, moves focus to the first focusable element in the dialog.

What happens instead?

The user focus is set to the browsers URL bar once the user tabs beyond the last focusable element.

@domenic

https://html.spec.whatwg.org/#sequential-focus-navigation step 8 indicates that browsers' current behavior is correct.

Essentially there is a loop consisting of all sequentially focusable controls in the document, plus the UA's sequentially focusable controls. If in step 6 there is no next sequentially focusable control in the Document (i.e., candidate is null), then we will reach step 8 and focus the UA's controls (i.e. the URL bar). And if we're currently focusing the URL bar and the user is requesting to move focus into the Document, then the second half of step 1 takes over.

@koddsson & @keithamus

Essentially there is a loop consisting of all sequentially focusable controls in the document, plus the UA's sequentially focusable controls.

We think the spec should be altered to add an exception for modal dialogs.

The WCAG 2.0 defines the success criterion for focus trapping a dialog as:

A Web application brings up a dialog box. At the bottom of the dialog are two buttons, Cancel and OK. When the dialog has been opened, focus is trapped within the dialog; tabbing from the last control in the dialog takes focus to the first control in the dialog. The dialog is dismissed by activating the Cancel button or the OK button.

So we'd expect the HTMLDialogElement.prototype.showModal() to be able to trap focus in this way.

There's a reasonable expectation that dialogs should focus trap that can be seen by the virtue that Google Chrome will focus trap in dialogs such as the "Print" and "Bookmark" dialogs.

If the dialog element doesn't come with focus trapping developers will need to continue to implement focus trapping in "user land" to remain WCAG compliant.

Maybe related: #2171 and #7707

@scottaohara
Copy link
Collaborator

scottaohara commented Sep 30, 2022

I think this issue is worth discussing, as anecdotally I both know people who appreciate that keyboard focus can easily go to the browser chrome when a modal dialog is open, as well as those that would rather it did not.

However, the issue as filed is not entirely accurate in what is required by WCAG, let alone ARIA.

  • WCAG is not normatively stating focus must be trapped within a dialog. The referenced doc is an informative understanding document about the keyboard trap success criterion, and the referenced text is providing an example of when a keyboard trap could be "OK". This is not guidance saying that modal dialogs MUST behave this way by any means. Rather, the normative WCAG spec makes zero mention of requirements for focus behavior in a dialog. The informative 2.4.3 focus order understanding doc does talk about limiting focus behavior within a dialog - but again, this is in the context of a scripted custom dialog and was written long before inert or <dialog> were widely available (more on this towards the end of my comment).
  • Part of the reason the ARIA Authoring Practices Guide (APG) modal dialog example behaves the way it does is because the purpose of the APG is to demonstrate how to use ARIA. And, without using native HTML features like <dialog> or inert, it is far easier to trap focus within the custom dialog than it is to achieve the behavior that the <dialog> element has. The APG is also not normative guidance. Rather, if you look at the ARIA specification, the actual normative guidance for a role=dialog is as follows (emphasis mine):

Authors SHOULD ensure that all dialogs (both modal and non-modal) have at least one focusable descendant element. Authors SHOULD focus an element in the modal dialog when it is displayed, and authors SHOULD manage focus of modal dialogs.

Both the APG modal dialog and the WCAG understanding doc were written long before the inert attribute or the <dialog> element were widely supported. And, the alternative to instructing developers to trap focus in the dialog would have been to tell them that they needed to ensure that all focusable elements in the web page, outside of the modal dialog, received a tabindex=-1. Doing this (outside of using the inert polyfill) was often prone to error, developers missing a focusable element from their query selector, or not actually being able to ensure all focusable elements could be removed from the tab order (e.g., focusable elements within an iframe from another source). I could go into more detail about what would be necessary, but that demonstrates the point that giving developers guidance to trap focus in the custom dialog is far easier than the alternative and outlining all the potential pitfalls.

So with all that said I want to repeat that I do think this is a conversation worth having and it did come up in conversations related to #7707. However, it is not accurate to say that the current behavior doesn't meet WCAG. Though it is understandable why people would expect this behavior, as trapping focus within a dialog has long been the most practical guidance for developers who were building their own custom dialogs.

@patrickhlauke
Copy link
Member

patrickhlauke commented Sep 30, 2022

Just dropping in to confirm what @scottaohara mentions above: WCAG does not normatively define how modal dialogs should or shouldn't behave in terms of focus.

WCAG gives examples in understanding documents, but these are, by their nature, non-normative (so treat them more or less as best practice suggestions, and not exhaustive, and pretty much as a SHOULD)

Another example, for instance, is in the understanding for 2.4.3 Focus Order [edit: ah, just seen that Scott also mentioned it in his edited comment above] https://www.w3.org/WAI/WCAG21/Understanding/focus-order.html

  1. A Web page implements modal dialogs via scripting. When the trigger button is activated, a dialog opens and focus is set to the first interactive element in the dialog. As long as the dialog is open, focus is limited to the elements of the dialog. When the dialog is dismissed, focus returns to the button or the element following the button.

But again, if a dialog does not do this for some reason, it's not immediately a hard failure (unless there's no logical rationale for it, and it does random things like allowing focus to stroll back into the underlying page). But there's certainly nuance, subjectivity, context-specific considerations.

@domenic domenic changed the title Align HTMLDialog.prototype.showModal() focus trapping to WCAG 2.1 Allow modal dialogs to trap focus, avoiding tabbing to the URL bar Oct 3, 2022
@domenic
Copy link
Member

domenic commented Oct 3, 2022

I've renamed this issue to reflect the above comments. Thanks @scottaohara and @patrickhlauke for setting the record straight.

@domenic domenic added normative change needs implementer interest Moving the issue forward requires implementers to express interest a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. topic: dialog The <dialog> element. labels Oct 3, 2022
@koddsson
Copy link
Author

koddsson commented Oct 3, 2022

Thanks all for the excellent explanations for someone that doesn't have a ton of experience in this field. They are all really helpful ❤️

Aren't the browsers' UI controls always accessible to users via a keyboard shortcut? I'd imagine that using those instead of jumping to the browser controls at the end of a modal dialog would be better. Still, I'd defer to experts on accessibility and screenreader users over that 😄

Does the Pop-Up API maybe solve all of this?

@scottaohara
Copy link
Collaborator

Aren't the browsers' UI controls always accessible to users via a keyboard shortcut? I'd imagine that using those instead of jumping to the browser controls at the end of a modal dialog would be better.

Using F6 can allow someone to jump to either the browser tabs or address bar - depending on the browser. Command + L is how to do it with Safari.

Again, anecdotally what's better will come down to the individual.

Does the Pop-Up API maybe solve all of this?

It does not. It's not meant to be used for modals.

@frex65
Copy link

frex65 commented Oct 7, 2022

From a purely personal perspective, I like that I can "escape" a page where a modal dialog hasn't quite been marked up correctly by tabbing out to the address bar. I really dislike it when the focus is trapped in a specific area. With ARIA menus, for example, my JAWS focus can get trapped within the menu until I make a selection, when sometimes I just want to back out without doing anything. Makes me feel as though I'm caught in a mouse trap :-(

@josepharhar
Copy link
Contributor

@keithamus @nt1m @rniwa @muan

@LJWatson
Copy link

Aren't the browsers' UI controls always accessible to users via a keyboard shortcut? I'd imagine that using those instead of jumping to the browser controls at the end of a modal dialog would be better. Still, I'd defer to experts on accessibility and screenreader users over that 😄

In this case it may not be the experts we should be listening to 😊

From the point of view of someone who doesn't know what a modal dialog is or how it's implemented, a dialog is to all intents and purposes another page.

In the page context you can choose to Tab out of the bottom and around the browser chrome, you can use a keyboard command to move straight to the address bar or open a particular menu, you can close the tab, and so on. This gives people a choice about how, why, and what they do to escape out of the context.

It seems logical (to me at least) for the same options to be available to people when in a dialog context instead of a page context.

For someone who doesn't recognise or understand the difference, I imagine it must be frustrating to discover that your usual method may no longer work.

@matatk
Copy link
Contributor

matatk commented Nov 22, 2023

This comment comes from W3C's Accessible Platform Architectures (APA) WG. A personal tl;dr from me is that I think everyone's in alignment on this. Input came from all of us; thanks to @niklasegger for drafting this.

We addressed this question in the course of several APA meetings and came to the conclusion that the current behavior of the native dialog element should be kept as it is. So, that you can tab from the dialog to the browser functionalities.

We see especially the benefit that keyboard users can, for example, open a new tab to look something important up or to change a browser setting this way. At the same time, the dialog element thus provides an additional natural escape mechanism (i.e. moving to the address bar) in, for example, kiosk situations where the user cannot use other standard keyboard shortcuts.

In addition, we also see how this can confuse some developers, as prior to the native dialog it was common when implementing a custom dialog component to really trap the focus. For this reason, we will also get in contact with the APG group to talk about a change in the guide for the dialog (modal) pattern. We think an additional note is useful, pointing out that when using the native dialog element, tabbing to browser functionality is normal and wanted, and does not need to be "fixed" by one's own hand. Since for many developers APG's guides are the go-to resource for implementing accessible components, hopefully this will prevent more confusion in the future.

@koddsson
Copy link
Author

It sounds like most people are in agreement that the current functionality is correct so I think we can just close this. Maybe there is a opportunity to make this position more clear in the spec?

In any case I really appreciate everyones time to make comments and share their thoughts ❤️ I haven't done a lot of spec work and it can be a bit daunting but everyone has been super nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a11y-tracker Group bringing to attention of a11y, or tracked by the a11y Group but not needing response. needs implementer interest Moving the issue forward requires implementers to express interest normative change topic: dialog The <dialog> element.
Development

No branches or pull requests

8 participants