jackbsteinberg/std-toast

Avoid Interactive Children

aardrian opened this issue · 9 comments

Looking back through the readme, I see the following:

More complex toasts, that don't fit the above content model, would require more custom handling on the part of the developer:

<std-toast>
  <p>Hello world!</p>
  <p>A second paragraph?!</p>

  <button>Action 1</button>
  <button>Action 2</button>
</std-toast>

That behavior is a dialog, not a toast.

Note that the ARIA roles I have identified in #25 (Map to Existing Roles) generally do not have interactive controls within them (other than to dismiss). They are informational.

Those roles generally do not receive focus when they appear nor should they. Adding interactive controls creates a more complex challenge, especially as I see other issues discussing where a toast should live in the DOM.

Anywhere in the DOM you place a toast that holds interactive controls will likely create both a reading order (1.3.2 Meaningful Sequence) and focus order (2.4.3 Focus Order) WCAG failure on a page/screen. At least not without a lot of native focus management supplemented by author focus management. We already know how difficult that is given the problems with native <dialog> implementations in browsers.

If the toast has a built in time limit before it disappears, then adding interactive controls means the browser must also provide a way, via settings, to override that time limit. Otherwise it will create 2.2.1 Timing Adjustable challenges for authors and users.

To recap, allowing toasts to contain interactive controls puts the burden on the user agent to:

  • handle all the focus management
  • provide a UI for users to adjust timing

Did you see the research? https://github.com/jackbsteinberg/std-toast/blob/master/study-group/. It turns out it's quite common for toasts to have at least a close button, and often an action button.

But yeah, it's of course a hard requirement that such actionable toasts are accessible and WCAG conformant, as they are all on all native platforms, and in at least some of today's web libraries. Thanks for pointing out specific ways toward ensuring that!

@domenic

Did you see the research? https://github.com/jackbsteinberg/std-toast/blob/master/study-group/. It turns out it's quite common for toasts to have at least a close button, and often an action button.

I did. It was part of the reason I opened this issue (though I failed to cite it). So while it may be common for toast implementations to have some sort of action button, that does not make it a good pattern nor one that must be emulated.

However, if allowing nested interactive controls (outside of a dismiss control) is defined as in scope for this proposed element, then we may be better off shelving this and revisiting <dialog>.

Going to echo support for this issue.

Outside of a close button which could be useful for sighted mouse/touch to dismiss a toast more quickly, the timed behavior of a toast message can make these components difficult for some people to navigate to, and can be frustrating if important interactive controls are used within. While it may be common to see such patterns in the wild, it doesn't mean it provides good inclusive user experiences. Often when evaluating the accessibility of applications, such interactive controls used within timed-toasts are issues that get brought up for remediation.

Taking a look through the researched examples of toasts or toast-like elements that "mentioned accessibility" the ones that had the best documentation or most closely resembled the functionality that would match the ARIA roles listed in #25 were Bootstrap, and Notyf. These did not have child interactive elements in their demos, outside of a dismiss button in Bootstrap's.

Material UI and Sales Force had examples of toasts with child interactive controls. Material's demonstration being good to show that the toast comes directly after the invoking element in the document order, so a keyboard user could get to the interactive control before a timeout. However, Material's toast could timeout while a keyboard focus was within the toast, which seems an oversight that should be avoided. Sales Force's toasts were all static when looking at their example page.

Sweet Alert 2 is a dialog pattern, so not really applicable here.

BlueprintJS has a general accessibility statement, but nothing relating to their toasts. Invoking a toast produced no announcement of the message, and their option to auto-focusing the toast should be avoided, as you'd be getting close to modal/non-modal dialog behavior by doing that.

While not flagged as mentioning accessibility, Polymer's toast appeared to be a demonstration of how I'd expect a native toast to behave as well, though in testing it did produce some duplicate announcements...but that could easily be sorted out.

Is it accurate to say that a toast is not a dialog because a dialog inherently requires a user interaction (e.g. "click yes or no"), and that a toast does not require a user interaction? Even if it has the option for one? Just want to make sure there's clarity about why a toast isn't just a slightly different approach to a dialog, especially if they can contain user interactions.

@jimkeller I think the interaction itself is not the limiting factor. Check how the dialog role is defined:

A dialog is a descendant window of the primary window of a web application. For HTML pages, the primary application window is the entire web document, i.e., the body element.

Dialogs are most often used to prompt the user to enter or respond to information. A dialog that is designed to interrupt workflow is usually modal.

Compare with the status role (a scenario where framework toasts are used):

A type of live region whose content is advisory information for the user but is not important enough to justify an alert, often but not necessarily presented as a status bar.

Authors SHOULD ensure an element with role status does not receive focus as a result of change in status.

The <dialog> element corresponds to the role (in cases where browsers have implemented it correctly).

Maybe instead of the matrix (table) comparing features from the assorted frameworks, we should be looking at one comparing the assorted standards-defined roles — which have accessibility built in already and are at least on track to be implemented by browsers and AT.

No time today for a PR (because this is not my day job), so I will have to sit on this for now.

Within the time I took to research existing toast implementations I didn’t spend the time accessibility testing each, and now that I am creating a more in-depth accessibility study I appreciate the follow-up on this particular concern. The research was largely focused on gauging what functionality toast libraries provide, as a way of understanding how they’re used on the web in general. And from that research it seems that placing an action on an ephemeral pop-up notification is a pattern that UX developers seem to often desire from their toast implementations. With this proposal we’re trying not to rescope what developers consider to be a toast, but to instead implement an element that follows the existing patterns in a way that’s accessible for all. If we can’t build a standardized toast for all users, then developers will continue to use imperfectly accessible solutions, and certain swathes of the web population will miss out on features that make the web a richer application environment.

With that said we’re going to be concentrating efforts on designing the accessible action-toast experience as best we can, with helpful community feedback like this issue. This is our current idea of what that looks like:

  • User is navigating the page when a toast pops up
  • The toast is visually displayed on the page
  • The contents of the toast is announced by a screen reader
  • The action and close buttons within the toast (if they exist) are the next two elements in the tab order
  • While the user focuses within the toast it will remain open
  • If the user tabs away they will resume tab navigation, and eventually the toast will close

In combination with some further accessibility efforts, such as exploring the best solution for default timeout, we’re hoping this model will allow us to create a maximally accessible toast. We’re also hoping that this will be feasible with current web technologies and accessibility patterns, and these comments have been very helpful in providing benchmarks to check our accessibility solutions against. This is all still under iteration, and further help / input on how to build such an intuitive, inclusive toast is very much welcomed :)

Thank you for mentioning the dialog and log roles, we need to look further into those as we progress in our accessibility study to see if they would make sense to include on action-toasts / multiple toasts.

As far as the distinction between role=”status” and role=”alert”, since alert has the attribute aria-live=”assertive” we’re leaning toward automatically applying alert to toasts that have action buttons. This way a screen reader will always read out the contents of the toast as it comes in, so the toast will not time out before the content is read and users get a chance to take action or not. This decision may however be left up to developers when they choose a theme for the toast, more discussion on this (and on changing the name theme) in #18.

@jackbsteinberg

  • The action and close buttons within the toast (if they exist) are the next two elements in the tab order

Big red flag here. Are you suggesting the toast is going to steal focus?

Thank you for mentioning the dialog and log roles, we need to look further into those as we progress in our accessibility study to see if they would make sense to include on action-toasts / multiple toasts.

HTML already has a <dialog> element. While browsers may have implemented it poorly, let's avoid feature creep by trying to mimic it here.

As far as the distinction between role=”status” and role=”alert”, since alert has the attribute aria-live=”assertive” we’re leaning toward automatically applying alert to toasts that have action buttons. This way a screen reader will always read out the contents of the toast as it comes in, so the toast will not time out before the content is read and users get a chance to take action or not.

I left thoughts about the types on #18 (comment).

But here you are weaving together multiple issues (time-out, focus, announcements) and (I suspect) making an assumption about what would be useful for a screen reader user.

If there is a control and screen reader user must take action, then avoid the time-out, steal focus, and make an alertdialog. Please read up on that pattern first.

If you agree it is a fit, then it is probably outside the scope of toast and belongs with the native <dialog> implementation.

since alert has the attribute aria-live=”assertive” we’re leaning toward automatically applying alert to toasts that have action buttons. This way a screen reader will always read out the contents of the toast as it comes in, so the toast will not time out before the content is read and users get a chance to take action or not.

I can imagine a couple of potential issues with this:

  • In some (all?) screen readers, "assertive" will flush the event queue of live notifications, not just interrupt the current speech. So if you have multiple alerts, there's a chance you wouldn't actually hear them all, or it would be confusing, as one pre-empted another. It would require some care on the developer's part to prevent this, so maybe some guidance can be provided to not use toasts in a context where you could have them appear frequently.

  • Users can adjust the reading rate of their screen readers. While most users do (eventually) adjust their rate to be very fast, there's no guarantee of this. It's possible for the toast timer to expire before the screen reader is done reading. What is the user's experience in this case?