Recently I wrote a bit on how I’d define a toast component, outlining UX concerns that should be considered if deciding to implement such a messaging mechanism.

tldr; a “toast” (hopefully renamed “message” or something else not food related) would be an element/component that briefly pops up to convey a status message, and then dismisses after a timeout. Unlike a modal dialog, it would (should) not steal user (keyboard) focus upon being invoked. This means it would need to act as a live region to ensure that assistive technologies, such as screen readers, would announce the content when it appears on screen.

But while effort is being spent on coming to consensus on this new custom element, it got me wondering if maybe what we really need is a good hard look at HTML’s output element.

For example, a few lines of CSS, and a bit of JavaScript, and an output could be the native HTML basis for a toast component, today.

Let’s have a look…

Some background on the output element

The output element was added in W3C’s HTML 5 Working Draft 12 (February 2009). Prior to this working draft, it was referenced in HTML 5, but linked to its initial definition in Web Forms 2.0.

From its original definition in the HTML specification to present day, some details about output and how it could be used have evolved, but the element has always been included in the family of Form elements.

As per its original Working Draft definition:

The output element represents the result of a calculation.

That’s a very narrow use case. But the early definition of some HTML5 elements had other very specific use cases that eventually evolved into something more useful.

By the time HTML5 reached W3C recommendation status (2014), and to this day in the HTML Living Standard, the introduction of the element had been updated to a version of the following:

The output element represents the result of a calculation performed by the application, or the result of a user action.

Compared with output’s original introduction, this updated description could (and in my opinion should) allow for output to be interpreted as more than just an element to display a computation result. Rather, it can be an element to display a feedback message based on user interaction / in general.

Now, I’ll admit that this interpretation may be possible only due to a potentially errant comma in the description. However, I’d submit that the expanded allowance makes the element far more useful, especially considering the defined accessibility API mapping for the element (more on this in a bit).

That said, examples for using the element have often included a code snippet much like the following, which have done little to illustrate the element’s potential broader use beyond a way to dynamically math form control values:

<form oninput="added.value=parseInt(i1.value)+parseInt(i2.value)">
  <input type="number" min="0" name="i1" value="0"> +
  <input type="number" min="0" name="i2" value="0"> =
  <output name="added">0</output>

In the above example, updating the values of the number input fields would result in the value of the output dynamically changing to match the values added together.

Note that while the form's oninput modifies the value of the output, the output element itself does not accept a value attribute. The output's "value" is represented by its child content.

Naming an output

Another aspect of the output element that changed from its original WD inclusion was in the (WD4, March 2010) output became a labelable element. This change meant that, like many other form elements, a label could be associated with an output like so:

<label for="idref">
  My Label:
<output id="idref"></output>

Labeling an output can be beneficial in situations where the output may not immediately follow an element, or elements that will modify the output’s value. Where supported, a semantic relationship can be communicated to assistive technologies, such as screen readers (again, more on this in a bit).

For example, a labelled output could exist at the end of a form where the modification of various controls contributed to the final value of an output (again more dynamic mathing).

Skip to after iframe

Skip to before iframe

The naming of an output, and location of the dynamically updating element in the DOM should begin to make you wonder about of the accessibility of output. If it can be named, and its content can be changed, how can these features be exposed to the accessibility API?

The accessibility of the output element

Looking to the HTML Accessibility API Mappings specification (HTML AAM), it notes that browsers need to map the output element to ARIA’s role="status". As mentioned on MDN’s page about the output element:

Many browsers implement this element as if it had a aria-live attribute by default…

Actual implementation is meant to be more specific than an aria-live attribute. The status role is one of the live region roles defined in the ARIA specification. Summarized from ARIA’s definition, status is:

A type of live region whose content is advisory information for the user but is not important enough to justify an alert… Elements with the role status have an implicit aria-live value of polite.

Additionally, role="status" can be given an accessible name by authors, as output also allows by being a labelable element. Again, this differs from a generic element with an aria-live attribute, as not all elements (depending on their role) can be provided an accessible name. For instance, a div will not consistently expose an accessible name if given one via aria-label.

Testing the output element shows, that aside from some quirks (some worse than others), modern browsers expose the element as a live region. IE11 not being a modern browser will need to be patched to treat output as a live region. But, that should surprise no one at this point.

Note: When originally writing this post, there was a bug with Firefox’s treatment of output. I had filed a bug with Firefox which is now closed and marked as fixed. However, while marked as fixed, support for output with Firefox/Android/TalkBack is still lacking.

Allowed child content

In regards to the type of content that can be valid children of an output, the element accepts Phrasing Content. So no headings, lists, or other sectioning or grouping elements like article, section, div, etc.

The allowed child content is also important to note for the way that live regions work with screen readers. Screen readers announce live regions by taking their child content and announcing it as a single text string. This means that if there are any links, buttons, or other elements with semantics that are typically exposed by screen readers, that information will not be conveyed in the live announcement. That’s not to say that, if navigated to, the elements won’t expose themselves as expected. Just that if an output had the following markup injected into it:

<p><a href="...">Undo</a> your changes.</p>

That would be announced as “Undo your changes” by a screen reader, without any mention of the link’s semantics. Elements with sectioning or grouping semantics would also not have their semantics relayed, and possibly not even their subtree content either.

Concise, simply marked up messages are key for well performing live regions. Think of these restrictions as guardrails to keep your content understandable and accessible!

Quirks with the output element

As I mentioned before, beyond IE11 not treating output as a live region (without some additional ARIA intervention) there are some quirks with how output is exposed by screen readers. Some more digging is necessary to determine the root of some of these issues, but the following should be considered if looking to use the element as is:

Firefox and TalkBack: incomplete support

While the output element produces live region announcements on desktop, Firefox on Android still has issues. Injecting content into the output does not produce a live region announcement. However, if the output has been given an accessible name, injecting content into it will produce a live region announcement of the accessible name. e.g., <output aria-label=test> would announce “test” when content was injected into the output. Unfortunate.

Chrome and TalkBack: Accessible name issue

There is a significant issue when Chrome is paired with TalkBack, if an output has an accessible name provided by a label, an aria-label, aria-labelledby, or by a title attribute.
If an accessible name exists, TalkBack will only announce the accessible name of the status region and not its dynamically injected content. An exception to this is if the injected content also contains an interactive element like a link. In this instance though, TalkBack will be redundant in some of its announcements of the injected content.

Chrome and TalkBack: auto-announcing live regions

TalkBack and Chrome will also auto-announce the existence of any output that contains default content, or an accessible name, on initial document load or sometime refresh. This is not an issue specific to the output element, but with most live regions that don’t default to aria-live="off".

Other quirks

  • macOS Safari (Webkit) with VoiceOver will announce the role of an output as “output”. For comparison, Chrome and VoiceOver will announce an output with an accessible name as a “status” role, as would be expected per its intended mapping.
  • Other browser / screen reader pairings may not announce or make available the accessible name of the output, even though its a labelable element.

Bridging Gaps

As with other features in HTML that have not been fully adopted, a polyfill could be written to mitigate gaps with output support in various browsers.

For example, while desktop Firefox doesn’t support output’s live announcements, it does support the status role itself. So adding role="status" to an output element:

<output role="status"></output>

works much like the workarounds we have had to do for implementing landmark roles with their native HTML counterparts. Which, fortunately we don’t have to do as much anymore.

Additionally, role="status" is recognized by some screen readers with IE11, and using it on an output element alleviates some of the TalkBack issues with Chrome.

A toast to the output element…

The output element can be particularly useful as HTML’s native solution for ARIA’s live regions.

In fact, rather than spinning up a whole new element that would require buy-in, implementations and testing, and consensus on how it should work and what should be allowed within it… maybe the existing output element could get updated, making it more than an element that is used to show how to dynamically render the value of addition examples.

Maybe some new native HTML attributes for allowing assertive or polite live region support could be created and allowed on the element. Maybe a new type to mimic ARIA’s different live regions.

One its most important feature, unlike many other form elements, is that its fully styleable with CSS, right now. Meaning that it can easily be used to create global alerts, status indicators, notification logs, or even popup messages, a la toast.

An example page using the output element and some CSS to make a toast component.

An example page using the output element, paired with role="status" to create a toast component that broadens its support in browsers.

output alone, even if updated, won’t be the single solution for creating a native toast. But it would sure be nice to better use and improve the HTML we already have.