Defining ‘Toast’ Messages
In current user interface terms a toast is a message that appears on the screen; it is often short, often appears only briefly, and often animates up from the bottom (like a piece of ghostly yet precisely-crafted toast), though other directions and a fade-in/-out is common.
When Google proposed
<std-toast>, it looked at a dozen libraries and found toast was commonly used to describe this pattern (or something like it), with snackbar and alert also in the mix.
Gilmore Davidson took it a step further and grabbed 44 design systems to look at other names, finding variations on toast, alert, and notifications, along with noty and growl (for the pre-OSX days of Macs).
Google already did some of the work with its
<std-toast> proposal. Its collection of 12 libraries were compared on 28 features. Of those 28 features, only one feature was common to of all of them — having a message. Interestingly, the feature
mentions accessibility was only listed on 6 of the 12.
Beyond those dozen libraries, the core feature across implementations generally seems to be a message that often goes away after a set period of time.
Few (none that I have found so far) of the existing toast or toast-like notification patterns in the wild will pass a WCAG audit. Instead of reviewing each of the ~50 examples, I am going to break down some of the broader concepts and risks that you can bear in mind when writing your own toast-like notification or reviewing one to use in your project.
There is no native toast-like implementation in HTML (though
<output> is the closest and may be a starting point for some uses cases). Therefore, the semantics and interaction patterns for assistive technology must be defined with ARIA.
Conversely, ARIA 1.2 contains roles that do not have native HTML counterparts, as outlined in 2.14 Aria roles and properties not available as features in HTML. The roles that appear to most closely match the toast concept are:
Note that none of these roles talks about how it should look, but instead how each functions and exposes itself to accessibility APIs.
None of these roles is a fit for rich content nor interactive children. Since they all map to live regions, a screen reader will announce the raw text within, without any of the structure. A keyboard user won’t be able to get to the nested interactive control without a very clear path. If you need to convey structure or include interactive controls, then you will need to move focus to the container and make it persistent. Essentially you will need a modal or non-modal dialog (and accompanying
Generally live regions must exist on the page at render. This primes the browser to monitor it as it builds the accessibility tree for the page. If you try to create (or convert a container to) a live region when you need it, it likely will not work. Also be careful that you are not hiding it with
display: none, or at least test it it with your target screen reader and browser combinations.
marquee are not a good fit as these roles have an implicit
aria-live value of
off, meaning they will not expose themselves to accessibility APIs as the others might. Both of those roles seem most likely to be on the chopping block for ARIA 1.3.
alert role is for important information that is typically time-sensitive. It has an implicit
aria-live value of
assertive, which means it will interrupt whatever the user is doing. This will also stop a screen reader from finishing whatever it was saying before the alert interrupted it (and will not pick up where it left off) which can make a user feel stranded.
Focus should not move to this control. If there is interactive content that requires focus, not only is the message not a toast but it should have an
alertdialog role and probably be modal.
log role is a fit when the order of the messages matters. The reading order is a function of when new content is added, and that new content should only be added at the end. It has an implicit
aria-live value of
polite, which means it will wait for the screen reader to finish speaking before announcing its content, and then only announcing new content. It should not receive focus.
status role is the most generic of the three. It has an implicit
aria-live value of
polite, which means it will wait for the screen reader to finish speaking before announcing its content. It also has an implicit
aria-atomic value of
true, meaning (unlike
log) a screen reader will announce its entire contents even if only one thing was added to existing content in the container. It should not receive focus.
By their very nature, toasts are likely to fail a WCAG audit right out of the gate if some effort is not made from the start. Following are WCAG 2.1 Success Criteria you should keep in mind when building your own or testing one of the existing options.
I have selected ones that I feel are at a higher risk of getting wrong. Sure, you can still mess up contrast, alternative for an embedded image, and so on, but the risk is not necessarily greater in toasts.
1.3.2: Meaningful Sequence (Level A)
Generally these messages appear at the start or end of the DOM. If you place them elsewhere, they may confuse screen reader users as they navigate through the page. Jamming each message into the middle of the page while it visually appears elsewhere can be weird and may violate 1.3.2.
1.4.4: Resize text (Level AA)
Users can resize text either by zooming in the browser or by setting a text size in the browser. For cases where the user has zoomed or scaled text, be sure the containers do not clip the messages, that they avoid scrollbars, and ideally do not obscure what the user is trying to do. 1.4.4 offers some additional context.
1.4.10: Reflow (Level AA)
If you do end up stuffing scrollbars into your message container, then make sure you do not have both horizontal and vertical scroll bars at the same time or you may be violating 1.4.10.
2.1.1: Keyboard (Level A)
As above, if you have scrollbars then you have to allow a keyboard-only user to scroll. Which means the container has to be keyboard operable. Which means it has to accept focus. Otherwise 2.1.1 will catch you here. Similarly, if there is a dismiss button or interactive content, the same concern about keyboard focus applies.
2.2.1: Timing Adjustable (Level A)
This one is the most relevant to toasts. If you follow the pattern where they go away after a few seconds, then you are in violation. There are ways around it, detailed in the 2.2.1 Understanding document, and includes letting the user adjust the duration in advance, allowing the user to extend their display time on a case-by-case basis, or letting the messages display for 20 hours.
2.4.3: Focus Order (Level A)
If your toast has scrollbars (see above) or has an interactive control of any kind, then it has to receive focus in a way that makes sense to a user. 2.4.3 outlines the overall concept, but from a usability perspective consider that messages at the end of the DOM will not be easy for the average keyboard user to get to — especially if they disappear within a few seconds.
3.2.4: Consistent Identification (Level AA)
However you choose to implement your messages, and even if you mix different types corresponding to the different ARIA roles above, 3.2.4 says that each type should be programmatically consistent with one another. Good UX would also tell us to make sure they look and behave the same or similarly across types.
4.1.2: Name, Role, Value (Level A)
If you give the messages a good accessible name (assuming they can receive focus and have some structure), correctly use the appropriate ARIA roles, and otherwise do not over-engineer them, then you should pass 4.1.2 without issue. The individual messages themselves are not that complex.
4.1.3: Status Messages (Level AA)
Spend some time with the 4.1.3 Understanding document. It breaks down and provides examples for how to use the
status roles in more detail than I do above and with examples.
These are not risks of failures. These are UX concerns that roughly map to WCAG Success Criteria.
1.4.13: Content on Hover or Focus (Level AA)
Users may expect to dismiss toasts by pressing Esc and you may choose to add that support. If you have code in place to satisfy 1.4.13 somewhere else on the screen, then make sure to test what happens when a toast appears while a user is dismissing a tool-tip or hover menu. A user may end up dismissing the notification by accident before seeing it.
2.5.5: Target Size (Level AAA)
If you put a control to close / dismiss the message, make sure it is big enough. This can be tricky when you want to keep the container as small as possible and you do not want a giant button enlarging it more, but your touch users will benefit. While 2.5.5 is a Level AAA criterion, it is a best practice to follow as I argue in my post Target Size and 2.5.5.
The first thing you have to do is accept toasts will be missed by users.
From there you can explore strategies to mitigate that very real use case.
1. Messages Holder
Conveniently, this limitation has been addressed in all modern operating systems. On Android, heads-up notifications behave similarly to toasts and are collected in the notification drawer (read the Android notifications documentation). Similarly, iOS has a notifications center where it collects notifications for you to view later and manage (iOS notifications info)
Windows 10 has its action center that slides out from the side of the screen and contains a notifications panel to let you scroll through any of its toast-like messages you may have missed or dismissed (where to find the action center). On macOS you can get to notifications from the notifications center, much like Windows 10 but from the upper right corner.
These are not snackbars, even though that unfortunate name might imply a place to get a stack of toast. A good terrible example is the Ignite UI for Angular Snack Bar, which consists of single messages with terrible contrast that cannot be recalled nor accessed via keyboard.
Messages Holder — Advantages
For a trained user this can be a boon. If you add a shortcut for users to jump directly to the message center then they can quickly check for any they have missed. It leans on a pattern already extant in operating systems, so it should be familiar to skilled users.
This approach can also address 2.2.1: Timing Adjustable by ensuring the messages never go away until a user dismisses them. Assuming your users know this and can access the messages holder. The entire container may qualify for a
log role as outlined above.
You can call it a toast warmer.
Messages Holder — Disdvantages
Users have to know this message center exists. Casual users may never be aware no matter how much you document it, tell them where it is, or provide shortcuts to access it. For a screen reader user you will also have to make it relatively easy to access, perhaps using landmarks. Keyboard-only users cannot jump around a page as a screen reader user can, so plan to test with users for the best location in the DOM for the trigger to access or display the messages.
The use of dark patterns that display message notification counters to trick people into clicking a thing means some users new to your screens (or casual users) may be wary.
2. Static Messages
Do not use toasts, at least not the animated timed version. Add messages to a region at the top of the screen so that all users can see and dismiss each at will. This will work across browsers and assistive technology and does not require any special training to understand. It may seem old school, but it is almost the MVP of a messaging pattern (whether you think MVP means Minimum Viable Product or Most Valuable Player, I stand by my statement).
Even if you want to go down the path of toasts and a toast warmer (that is its name now), this approach can be how you build it first. Then progressively enhance it to become the toasts pattern you want after your application confirms all scripts and styles have loaded. If
<output> is the closest thing we may have to a native toast, then you could start experimenting there.
Static Messages — Advantages
For untrained or unskilled users, the messages will always be available (and visible) and require no special interaction nor steps to access them. If they are contained in a landmark or have a heading, a screen reader user can quickly get to them. Keyboard-only users do not need to jump to the container or messages unless to dismiss them, and the control to do that would be in the focus order already.
Static messages satisfy 2.2.1: Timing Adjustable out of the gate. Since you can generally lean on styles for the overall screen, accessibility concerns you addressed there for contrast and text size should apply here as well. You may even ignore the roles I outlined above if you are unfamiliar with them or cannot test with AT.
Static Messages — Disdvantages
A stack of static messages can get lengthy, particularly if the messages are mostly just status updates. While you can address this by using a scrolling area or a disclosure widget, you lose the benefit for users of being able to glance at all the messages.
If the amount of messages is that much of an issue then the key disadvantage to this approach is that is has potentially laid bare a bigger UX problem — throwing too many messages at users. Which means you should put this problem down and instead go look at the rules for your overall messaging system to ensure you are not overwhelming users.
3. Do Nothing
If you find yourself saying,
Hey, if my screen reader, zoom, or keyboard-only users miss some of these messages, it’s not a big deal then you have a larger question to ask — do you even need those messages?
Your error messages still have to pass WCAG Success Criteria 3.3.1: Error Identification, 3.3.3: Error Suggestion, and maybe 3.3.4: Error Prevention (Legal, Financial, Data) with or without toasts. Your status messages must still conform to WCAG 4.1.3.
Maybe all other messages are just not important. Maybe you need not present a toast with an order receipt. Maybe you can rely on the browser telling the user when the file is downloaded. Maybe a page redraw is sufficient evidence the changes were saved. Maybe you are just adding noise.
Do Nothing — Advantages
The biggest advantage to you as a developer is that you are not adding complexity. No additional work is needed for a feature that maybe does not offer much value. That’s one fewer item in your backlog.
For users, that is one fewer interaction to grok (comprehend), less code to download, less code for the browser to parse, less memory or CPU overhead. For some users, any messages can add cognitive load they may not have the capacity to manage, complicating an existing stress case or compounding anxiety for some.
Do Nothing — Disdvantages
If your design is genuinely constrained and temporary messages are a solution to that constraint, then this approach will not work for you.
For specific users in specific scenarios with specific needs, they may rely on a regular stream of visible updates. It may be how they monitor the heartbeat of a system, even if the system is just regularly saying,
Not dead yet; going for a walk. Excluding these kinds of messages can make them worry something is amiss.
Toasts are a pattern best used carefully and only after testing with users — your users and their technologies. If you opt to build toasts, be certain your timelines account for accessibility testing. If you instead use toasts from a third-party, then be even more certain your timelines account for accessibility testing and potentially changing to a different third party solution.
- Scraping Burned Toast by me, June 14, 2019
- A toast to an accessible toast… by Scott O’Hara, July 8, 2019
Update: 15 January 2020
Ana Tudor took my kawaii toast SVG and made it better by hand-recoding it to make it smaller. Her optimized version is at the top of this post now.
Gave handcoding that SVG a try: codepen.io/thebabydino/pen/Exa
A little over 1KB (down from 2.9KB) pic.twitter.com/6fdRFZRaVO
Update: 18 March 2020
Above I talk about a Messages Holder (which I rename toast warmer) and explicitly qualify that it is not a snackbar. In fact, I mostly ignore snackbars because they are generally poorly built, though I do not go into much detail why.
Conveniently, Adam Silver does that in his post The problem with snackbars and what to use instead. Mostly his feedback about alternatives aligns with what I list above, but in far few words.
Hey Adrian! I don’t know if you get it enough, but I wanted to share some feedback that your site is invaluable. As much as we reference you on my team, we could build a slackbot to just link anything new you publish. :) But yep this post is super in-depth and also clear. It’s very hard managing announcements, and I agree that often the first step is to ask yourself if the component you’re choosing is the right one. If the toast does make sense, then this is awesome detailed advice.
In response to.
Ryan, thanks for the feedback. I generally only hear IRL if the stuff I post is useful, so it is nice to hear that some of it is.
Really pleased to see the UX side of toasts discussed here. Like all the patterns designed to be small and unobtrusive, there are complex access needs that often get overlooked. Thanks for digging into the detail!
In response to.
Julie, thanks. It seems the smaller the pattern the more easy it is to overlook the complex needs.
Thank you for this very detailed and useful post (and all the others! I second Ryan). You mention a possible issue with WCAG criteria 1.3.2: Meaningful Sequence. I wonder how you would go about building a component with toast messages in it. A file uploader for instance. The toast would be in the middle of the DOM… Do you think that would fail the criterion? Testing didn’t seem to reveal any issues.
In response to.
Martin, thanks for the feedback.
If you insert the content into the DOM in a place that makes sense for the user in the sequence of the page, then ace. In my experience, richly interactive web components can rarely exist in a vacuum due to interplay with live regions and focus order.
If you already tested with users (keyboard, SR users as well) and had no issues, then regardless of where it appears in the DOM it may be fine where it is. As long as you confirmed there is no conflict with its live region and any page-level live region.
Another fantastic post, as usual. Though I have to take issue with one point:
…toasts and a toast warmer (that is its name now).
I admire the boldness. But why not call it a toaster? The toast pops up (seemingly out of nowhere), then remains semi-obscured until you’re ready to deal with it (I’m assuming that “toast warmer” isn’t a colloquial term for toaster that I’m not familiar with).
In response to.
Toasters are a one-time heat-and-deliver model (such as rendering the page), toast warmers are where you store toast until you want it. Also, you can fork a toast warmer, if you fork a toaster you can get electrocuted.
Just want to explore a potential downside to a toast warmer as a landmark region: what to do about the common situation where there are currently (or initially) no messages inside it. It’s effectively an empty landmark region – is that a problem in your view? Do you think there’s a need for an explicit “no messages” conditional placeholder, or a permanent “message count”?
In response to.
Also: which landmark role would you typically recommend? Will a
complementarysuffice, or is a labelled
role=regionbetter? How about a making the toast warmer a live (but not landmark) region which lives alongside other content inside the
In response to.
An empty landmark region is no big deal if its accessible name is set. If you have a region named Messages and there is nothing there, that tells the user there is a place for message but there are simply no messages yet.
I would not make it a live region. Live regions announce the raw text without the structure or semantics. Problematic if you have links or lists or whatever.
And yeah, I would start with a
regionrole (with an accessible name, of course) and then test with the users of the screens to see if that is clear enough.
Leave a Comment or Response