A toast to an accessible toast...
You may have recently read Adrian Roselli’s Scraping Burned Toast, Chris Coyier’s summary of the current “toast conversation”. Or maybe you’ve browsed the GitHub repository for A Standard ‘Toast’ UI Element and its WICG discussion thread.
Regardless of how familiar you are with the concept of a “toast”, there has been an attempt to pave the cow paths that different UI libraries have created for said crispy bread. Unfortunately, the accessibility and inclusive UX of a toast component varies quite a bit depending on which component library you review.
I’ve commented on this a bit in the previously mentioned GitHub issues, but it got me thinking of how I might outline the functionality for a toast / messaging component. Here are some quick-ish thoughts on that…
Defining a toast
A toast component should deliver a concise message in the form of a consistently positioned popup. Often, a toast message appears from the bottom of a screen or viewport. This is particularly true for small screen devices. A “growler” notification could also be considered a type of “toast”. They generally appear from a top or bottom corner of the screen or viewport. Regardless of whatever a standardized positioning might be, authors would need to make sure that they were consistent in the positioning of their toasts. People don’t much appreciate having to guess where notifications are going to popup from.
At a high level, toasts should be used to indicate the completion of a task or process initiated by the user or the application itself. For instance, a notification verifying the saving of a file, that a message had been properly sent, or a that a meeting was about to start.
If someone were to ignore, or miss a toast message due to its timed display, there should be no negative impact on their current activities or the status that the message conveyed. Using the previous examples, ignoring a toast message would still mean that a file was saved, that a message was sent, or that a meeting was about to start.
That said, what’s important to different individuals is not necessarily a binary. WCAG 2.2.1: Timing Adjustable should be considered in creating a toast component to ensure that all users can have adequate time to acknowledge a toast’s message. Outside of some feed-like (“snackbar”? do people consider toast a snack? Don’t let hungry people name the web, please.) implementations of toasts, where the messages may not remain visible but get appended to a log of notifications, few toast components take into account this Level A WCAG success criteria.
Inclusive UX of a toast
A toast component should be considered a type of status message, and thus should be injected into a
role="status". Or, if the toast messages will be ‘logged’ so that they can be reviewed later (this is a good idea btw), then they should be injected into a
role="log" This will ensure that when a toast is displayed on screen, its contents will be “politely” communicated to assistive technologies, such as screen readers.
Ideally, a toast component should contain no interactive controls, as by doing so an immediate divergence of inclusive UX is introduced. The following reasons are the concerns that including interactive controls in a toast will create:
Live regions do not convey the semantics of the content they announce. A status message containing the text “Your message was sent.” Followed by a link or button with the text “Undo”. Will be communicated as “Your message was sent. Undo”. The semantics of “Undo” will not be announced. Which leads to the next concern…
- People using a screen reader can infer that the “Undo” may be an actionable element, but depending on the element used (again, link? or button?) means that they’ll have to guess which element they should try to search for, if they need to reach said “Undo”. Being that a toast is typically an element that is automatically dismissed after a short time (again a WCAG 2.2.1 concern), these users will have to figure this out quickly, and hopefully navigate to the control in enough time before the message goes away, if they in fact need to “undo” something.
- For sighted keyboard users, or for users who may be using a type of pointer device (mouse), but who have reduced mobility, they too are against a time limit for how quickly they can navigate through the DOM or move their pointer to the toast component.
- If a user is able to surpass all the above mentioned points, authors still would need to then include a function to manage focus. Upon activating “Undo”, focus would need to return to a logical location (the submit button for the message?) For other instances of toasts that contain “close” buttons, focus would need to be managed here too, otherwise focus could be lost and users would have to return to the top of the current document and navigate back to where they last left off.
- Another gap to consider is that a pop up message of any kind can introduce obstruction issues for people who have zoomed in browsers, or smaller screen real estate in general. (Maybe use a media query to not display as a popup?)
- For those who are using screen magnification software, but who are not using a screen reader, may be magnifying a portion of the page where the pop up message doesn’t appear. If there is an important control (again “Undo”) within this pop up, it could go completely unnoticed.
- Finally, per WCAG 2.2.1 Timing Adjustable, ideally there could be some sort of browser or OS level setting for the timing of messages to adhere to. Rather than setting an arbitrary time limit, the affordance for how long a toast message could display before dismissing (if at all) could be determined by end-users, similar to a high contrast or reduced motion setting can be respected.
Mitigating UX gaps for important interactive elements
If an action is important, and there’s no other means to perform said action, it should not be included within a toast component. But, if one were to want to work around the mentioned points of concern, and include an “undo” action within a toast, the following conditions should be true:
- The contained action is also readily available outside of the toast, in the primary document. e.g., if an item from a list was deleted it should be replaced by an “undo” button, instead of a full deletion, so that the toat’s “undo” wouldn’t be the only way to undo said action.
- Or, the toast message should be saved to a notification history page or component (see again ARIA’s
- Use a non-modal dialog to contain the message. You could even visually style and position the dialog to more closely resemble a “toast”, as defined by your style guidelines. While that may seem like a point of contention to “style a component to look like another component”… well, people don’t seem to have a problem styling links to look like buttons, and vice versa. Also, a “toast” doesn’t look anything like actual toast… so we’re already off to a horrible start with visuals aligning with names.
I’m sure that people could poke at this a bit more to come up with other UX considerations and functionality that a toast / messaging component should have. I hope you do, and if so, please make sure to contribute to the discussions.