When you activate a snackbar toast and the contents of the toast are announced to the user, the focus should also move to the toast. It _seems_ like the focus is lost at the moment / it is unclear where exactly the keyboard focus is when the toast first opens. When the toast is closed, focus should return to the original element that opened the toast (if it is still present on the page).
When you activate a snackbar toast and the contents of the toast are announced to the user, the focus should also move to the first interact-able element of the toast (like the action or close buttons). When you close the toast, focus should return back to the element that opened the toast.
While there are no specific aria guidelines for toasts, a modal dialog is probably the closest example:
https://www.w3.org/TR/wai-aria-practices-1.1/examples/dialog-modal/alertdialog.html
We've also been given this feedback from our users.
Steps:
Our keyboard-only users expect to be able to keep track of focus as they interact with elements that fire toasts.
| Tech | Version |
| ----------- | ------- |
| Material-UI | Latest as per docs |
| MacOS | Catalina 10.15.6 |
| Browser | Chrome Version 84.0.4147.135 (Official Build) (64-bit) |
We should be very careful with making this the default behavior. For UIs using the snackbar for notifications (possible displaying multiple) you don't want the Snackbar to steal focus.
I don't think Snackbar should be used as an alertdialog due to their positioning.
In the case of the Snackbar with an undo action it's probably better to add a keyboard shortcut. Otherwise it might be disruptive if you trigger an action and every time the focus is moved to an option "undo" element.
So there's a lot of nuance to this component. We didn't do a good job making it accessible by default especially due to the poor naming and customization points without oversight.
Some brainstorming on how to recommend better a11y (without having looked into prior art for accessible notifications/undo popups):
action is provided but provide some helper method that creates accessible actions (with shortcuts)We should be very careful with making this the default behavior. For UIs using the snackbar for notifications (possible displaying multiple) you don't want the Snackbar to steal focus.
I didn't think of a scenario where Snackbar was used for notifications, I see your point. However, in the case of Snackbar appearing after a user interaction, I think focus moving to the Snackbar could still be a valid scenario.
Even if we decide _not_ to implement moving the focus to the Snackbar when it's been opened, in any case there should probably be better visual indications of where the focus is after _closing_ a Snackbar (on https://material-ui.com/components/snackbars/#simple-snackbars, after you close the Snackbar you have no visual indicators as to where your focus is - it seems like focus is lost when the Snackbar is removed from the DOM).
I don't think Snackbar should be used as an alertdialog due to their positioning.
Any chance you could expand on this? Our use case would be one such as showing an alert dialog as a toaster after a user interaction (say, clicking a button to submit a form and having a dismissible "Success!" toaster appear on screen).
In the case of the Snackbar with an undo action it's probably better to add a keyboard shortcut. Otherwise it might be disruptive if you trigger an action and every time the focus is moved to an option "undo" element.
I agree, maybe my ask for the focus should move automatically to the "X" button of the snackbar instead of the first interact-able element.
Some brainstorming on how to recommend better a11y (without having looked into prior art for accessible notifications/undo popups):
- don't move focus if
actionis provided but provide some helper method that creates accessible actions (with shortcuts)
It's late in the day for me so you'll have to forgive me for not following this one 馃槀 - how would this work from a user perspective?
- ~add option to move focus~
I'm not convinced yet that we need it. A concrete example of a Snackbar where this should happend would help deciding what to do about it.- Due to its position portaling it seems ideal. Sequential focus order should follow the visual order so it would be disorienting if it would appear at the bottom visually but in the middle of the main content in tab order.
Portaling, if I understand correctly, would render the toaster in a different area of the DOM like in https://material-ui.com/components/portal/ - that seems reasonable but in that case I would definitely want to see focus moved to the toaster after a user interaction - otherwise I'm wondering would a keyboard-only/screenreader user have a hard time "finding" the snackbar on the page?
@eps1lon I really appreciate your thoroughness on this! A11y is so subjective - it's hard to know exactly what the right approach is.
PS I'll have a chat with some other a11y heads I know and will update here if I change my mind again 馃槀
Any chance you could expand on this? Our use case would be one such as showing an alert dialog as a toaster after a user interaction (say, clicking a button to submit a form and having a dismissible "Success!" toaster appear on screen).
That's not an alertdialog as it's defined in the ARIA authoring practices:
An alert dialog is a modal dialog that interrupts the user's workflow to communicate an important message and acquire a response.
-- https://www.w3.org/TR/wai-aria-practices-1.1/#alertdialog
ARIA is not as clear. A snackbar can definitely act as an alertdialog where you want the user to confirm but I don't believe this is the best UI for this type of notification due to its placement. Using it as an alertdialog is actually less accessible for sighted users I'd say.
it's hard to know exactly what the right approach is.
Definitely. It's why having concrete examples is so important when filing issues. It also reveals problems with a component if it can be used for too many UI patterns. Then it fails to provide real value to developers if they have to customize it before it actually works.
We already improved in that area by implementing a standalone Alert.
However, in the case of Snackbar appearing after a user interaction, I think focus moving to the Snackbar could still be a valid scenario.
At the top of my had I can't recall any toast-like element that should steal focus. A popular use case where you have it as a confirmation with an action to undo can be accessible by providing a different shortcut to undo e.g CTRL + Z which acts like onClick on the undo action. ESC would act like onClick for the dismiss button. The problem with focus stealing is that it is interrupting the workflow and you should have a strong reason for doing so. A confirmation message does not fall into that category in my opinion.
It's late in the day for me so you'll have to forgive me for not following this one joy - how would this work from a user perspective?
Basically something like <Snackbar action={<ShortcutButton shortcut="CTRL+Z" onClick={handleClick} />} . ShortcutButton would not be in sequential focus order but register a global keydown listener for CTRL + Z that calls handleClick.
It's probably worth revisiting what the Snackbar's intended use is:
https://material.io/components/snackbars#usage
Snackbars communicate messages that are minimally interruptive and don鈥檛 require user action.
Component | Priority | User action
-- | -- | --
Snackbar | Low priority | Optional: Snackbars disappear automatically
Banner | Prominent, medium priority | Optional: Banners remain until dismissed by the user, or if the state that caused the banner is resolved
Dialog | Highest priority | Required: Dialogs block app usage until the user takes a dialog action or exits the dialog (if available)
Thanks @mbrookes @eps1lon that all makes sense - I think Snackbar is the appropriate component for our "success" message use case but you're right, it doesn't need to get focus automatically because it doesn't _require_ interaction from the user.
The only thing we would need to clarify is what should happen to the focus if a user does manage to keyboard-navigate to the snackbar and close it before it fades away. At the moment, the focus disappears. Can raise a separate issue for that and close this one if need be?
@mbrookes So it would support the idea that the Snackbar should be portal, so it can't be reached with Tab?
To be fair, I believe that most applications use the Snackbar with a global dispatch system anyway (e.g. redux). So in practice, the Snackbar is most likely not reachable with Tab unless reaching the end (most likely) or the beginning of the page (depending on how it was set up). I have been advocating for something similar in https://github.com/mui-org/material-ui/issues/21053#issuecomment-630119128.
Regarding:
Keyboard focus should move to the Snackbar when it opens
Should it be deferred to the userland? Not something Material-UI handles in the core?
The only thing we would need to clarify is what should happen to the focus if a user does manage to keyboard-navigate to the snackbar and close it before it fades away.
As focus moves back to the body? What other behavior did you envision?
As focus moves back to the body? What other behavior did you envision?
One that doesn't interrupt the current workflow.
So it would support the idea that the Snackbar should be portal[led], so it can't be reached with Tab?
I'm not so sure... User interaction is optional, but there may be an action the user _wants_ to take, such as "Undo". What does a keyboard user do in that scenario if they can't focus the button?
What does a keyboard user do in that scenario if they can't focus the button?
Have a global shortcut which has a faster workflow for power users since you don't have to TAB and ENTER just hit a single combination:
Basically something like
} . ShortcutButton would not be in sequential focus order but register a global keydown listener for CTRL + Z that calls handleClick.
It's really hard to discuss this without user testing. It isn't clear to me if putting it in tab order isn't disrupting or if users even understand what's going on if they tab into an "undo" action that wasn't there before.
Most helpful comment
It's probably worth revisiting what the Snackbar's intended use is:
https://material.io/components/snackbars#usage
When to use
Snackbars communicate messages that are minimally interruptive and don鈥檛 require user action.
Component | Priority | User action
-- | -- | --
Snackbar | Low priority | Optional: Snackbars disappear automatically
Banner | Prominent, medium priority | Optional: Banners remain until dismissed by the user, or if the state that caused the banner is resolved
Dialog | Highest priority | Required: Dialogs block app usage until the user takes a dialog action or exits the dialog (if available)