Fast: it is possible to tab focus to background elements with a modal dialog open

Created on 15 Oct 2019  路  9Comments  路  Source: microsoft/fast

We've seen a few questions from FAST users about users being able to use tabbing to access background elements while a modal dialog is open. According to Aria spec focus should remain within modals - "Like non-modal dialogs, modal dialogs contain their tab sequence. That is, Tab and Shift + Tab do not move focus outside the dialog. However, unlike most non-modal dialogs, modal dialogs do not provide means for moving keyboard focus outside the dialog window without closing the dialog." (https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal)

While there are methods for authors to prevent focus going to the background it may be desirable for the FAST dialog to be better and containing focus without additional work on the part of developers.

This proposed change, for example, would actively direct focus back to the dialog if the parent document lost and then regained focus - https://github.com/microsoft/fast-dna/pull/2319.

bug

All 9 comments

IMO most developers would consider declaring a dialog to be "modal" as an important app level decision and would expect it to aggressively contain focus.

While there are methods for authors to prevent focus going to the background it may be desirable for the FAST dialog to be better and containing focus without additional work on the part of developers.

I think this is fair feedback. There's likely a few different ways to manage trapping focus. I'd like to see a few different proposals for how to solve this so we can evaluate them against one another. I have an idea I'd like to try out to see if it could help here as well.

After looking through this and digging into the spec, I think the scenario is best summed up in the three points below:

  • modal dialog traps focus where a user tabbing from the last element is returned to the first element in the dialog tabindex
  • modal dialog traps focus where a user hitting shift + tab from the first element in a dialog would be moved to the last
  • if a user left the flow of the document and were to return, they would be returned to the first focusable element within the dialog

Whatever solution we come up with should likely solve for the three issues above.

I question how much of an active role the dialog should take in managing the internal focus loop. IMO if the dialog reliably forces focus to a contained element in such a way that developers can choose how that is applied if they don't like the default behavior (ie. the previously focused element, or the first element, etc...) without us getting too entangled in that, that would be a win.

I question how much of an active role the dialog should take in managing the internal focus loop. IMO if the dialog reliably forces focus to a contained element in such a way that developers can choose how that is applied if they don't like the default behavior (ie. the previously focused element, or the first element, etc...) without us getting too entangled in that, that would be a win.

The overall ask is to meet the specification (https://w3c.github.io/aria-practices/#keyboard-interaction-7). Specifically:

In the following description, the term tabbable element refers to any element with a tabindex value of zero or greater. Note that values greater than 0 are strongly discouraged.

When a dialog opens, focus moves to an element inside the dialog. See notes below regarding initial focus placement.

Tab:
Moves focus to the next tabbable element inside the dialog.
If focus is on the last tabbable element inside the dialog, moves focus to the first tabbable element inside the dialog.

Shift + Tab:
Moves focus to the previous tabbable element inside the dialog.
If focus is on the first tabbable element inside the dialog, moves focus to the last tabbable element inside the dialog.

Accessibility is a huge part of our story. If there is a determinate interaction model for a control, I think we should provide that. If we want to create a way to allow developers to opt-out of that, I think that's fine but secondary to this ask. While we have minimal and limited opinion, accessibility and interaction models is one place where we've consistently chose to have an opinion. IMO, in places where we reliable can apply and include accessibility, we should be doing so.

Agreed - a modal dialog should follow the modal dialog spec by default. Providing a mechanism to opt out of that behavior shouldn't be too difficult, either by exposing a prop exposing opportunity for an interruptive callback.

Here is a library that helps find all focus-able elements in a node - we could use it or write similar logic for the default case.

https://www.npmjs.com/package/tabbable

I have updated the PR to implement a focus loop using tabbable. Still vetting and need to write tests but wanted to get it out for feedback.

closed with #2319

@chrisdholt Could this be done for the ContextMenu component as well? I can create an issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gqio picture gqio  路  3Comments

nicholasrice picture nicholasrice  路  5Comments

LucSuy picture LucSuy  路  6Comments

MarcSkovMadsen picture MarcSkovMadsen  路  6Comments

JuanElements picture JuanElements  路  4Comments