Across the web, you’ll see a range of sites that feature calculators for working out things like loan repayments, mortgage rates, tax, insurance, and more. Until now, we’ve had no way of semantically marking up the result of those calculations. Enter: the <output>
element! In this article, we’ll show you <output>
and some related JavaScript tricks. Let’s get cracking.
The Definition #
The <output>
element, new in HTML5, is used in forms. The WHATWG HTML specification describes <output>
very simply:
The output element represents the result of a calculation.
Along with the standard global attributes, <output>
also accepts the following:
for
- A space-separated list containing the IDs of the elements whose values went into the calculation.
form
- Associates the
<output>
element with its form owner. The value must be the ID of a form in the same document. This allows you to place an<output>
element outside of the<form>
with which it is associated. name
- The name of the element.
Implementing <output>
#
We’ll start by creating a simple example that adds two whole numbers together (Figure 1). We’ll use the new-in-HTML5 number
input type and the parseInt
JavaScript function to convert the input strings to integers:
Notice that we’re using the now-standard oninput
event, which has replaced the deprecated onforminput
event. Daniel Friesen has written a detailed article on the background and current support of oninput
. oninput
isn’t supported in IE8 and below, and its IE9 support is a little flaky, but you can work around these problems using the html5Widgets polyfill.
See a live example of the code in Figure 1.
As you’d expect, if you only enter a single value, the function returns NaN. It’s effectively trying to add a number and an undefined value, and 1 + undefined = undefined.
Using the for
Attribute #
Let’s build on the previous example and add the for
attribute to the <output>
(Figure 2). We need to add IDs to each of the associated <input>
s, just as we would with the for
attribute on a <label>
:
The valueAsNumber
Property #
HTML5 has also introduced the valueAsNumber
property of JavaScript input objects (specifically those of type number, date, and range). This returns the value as a number rather than as a string, meaning we no longer need to use parseInt
or parseFloat
, and the +
operator adds rather than concatenates:
Invoicing Calculator: An In-depth Example with Fallbacks #
For a more realistic example, let’s create an invoicing calculator that multiplies the number of hours by the hourly rate and adds tax to give an overall total (Figure 4):
See a live example of the code in Figure 4.
Nothing too complicated going on there. In fact, the scripting is so simple that even I can do it ;)
A Mildly Controversial Example Using <input type="range">
#
HTML5 also introduces the range
input type, which renders as a slider control in supporting browsers. With this input type, a user can enter an approximate value within a given range without having to be completely precise or directly type a numeric value. For cross browser compatibility, see Remy’s input range polyfill.
While researching this article, I found a number of examples using the <output>
element in conjunction with <input type="range">
as shown in Figure 5:
See a live example of the code in Figure 5.
Using <output>
to show the current value to the user seems like a perfectly reasonable use case to me, but it isn’t the result of a calculation
as the spec describes. I haven’t spoken directly to Hixie about this, but a couple of people on the IRC channel seemed to agree with, so I filed a bug report to request the definition be amended. Since writing this article, the bug has been resolved and the definition loosened meaning the above is now a valid use of output
. Hurrah!. I’ll update this article if something changes.
Browser Support and Polyfills #
The good news is that all modern browsers support the <output>
element to some extent. The bad news is that there are still a few gotchas.
Browser | Support |
---|---|
Chrome | 13+ |
Safari | 5.1+ |
Firefox* | 6+ |
Opera | 9.20+ |
Internet Explorer | 10+ |
* Firefox does support the <output>
element and the oninput
event, but it doesn’t support the valueAsNumber
property.
All the examples we’ve seen so far should work perfectly in Opera 11.5+, Safari 5.1+, and Chrome 13+. IE, as you might expect, is lagging somewhat, but support for <output>
is in IE10 Platform Preview 2, and support for oninput
is already in IE9.
In order to work around this in our simple examples, we’ll need to revert to the tried-and-trusted getElementByID
and parseFloat
(Figure 6):
See a live example of the code in Figure 6.
While this isn’t ideal, it’s workable until those less-capable browsers die a slow and painful death. Alternatively, you can use polyfills to plug the gaps.
To check support in your current browser, open up Mike Taylor’s support test page.
To support less-capable browsers, there are polyfills such as HTML5 Widgets created by Zoltan “Du Lac” Hawryluk. Zoltan talks you through the process in this detailed article on creating cross browser forms using html5Widgets.Polyfills #
Summary #
You probably won’t find yourself using the <output>
element all the time, but it’s useful in a whole host of situations. Calculating values on financial sites spring to mind, or outputting the current mouse position, or perhaps the goal difference in a table of sports teams. What other use cases can you think of for <output>
? Let us know in the comments!
Related reading #
- WHATWG HTML Specification for
<output>
- W3C Elements Wiki Page for
<output>
- Wufoo HTML5 Forms Tests for
<output>
- Mozilla Developer Network docs on
<output>
- Is
onforminput
Deprecated in HTML5 Forms? (And Why Should I Care Anyways?) by Zoltan Hawryluk - A HTML5 Browser Maze:
oninput
Support by Daniel Friessen - Fixing
oninput
in IE Using html5Widgets by Zoltan Hawryluk
36 Responses on the article “The output element”
In Figure 6 you specify the id of the inputs twice (2nd and last attributes).
Great article though, thank you.
@Bernhard – So I did, thanks. Have updated it now.
@Richard Clark
I’m the creator of webshims lib and I’m wondering, why you haven’t added the forms feature implementation of webshims lib to the list of possible polyfills.
If found something strange or you dislike, please let me know. I’m always trying to make webshims lib better.
Does the
for
atttribute have any behavior by default?What do we do with a web site in, say, German or Swedish, where the input and the output should use a decimal comma instead of a decimal point (the same goes for many, if not most, languages)? How do we use HTML5 in such cases?
@Bertil Wennergren
The value, which is shown to the user can be localized by the browser. Chrome is doing this for example. And you can simply change/transform the output to a locale you want.
I made a fiddle, which showcases the use of “toLocaleString”:
http://jsfiddle.net/trixta/Zw37n/
“The value, which is shown to the user can be localized by the browser. Chrome is doing this for example.”
For “output” elements or for “input[type=number]” or for both?
Exactly what does Chrome do now with “input[type=number]” and “output” in, say, an English web page in a German browser, or a German web page in an English browser? Does the decimal character depend on the language of the web page or the language of the browser? Or are there perhaps user settings for this?
only input[type=number] is localized to the language of the browser. so in a german browser the user will see 1,1 and in an english browser 1.1, but submit-data is still 1.1 in all browsers.
output simply shows what the developer puts into. it has no format restrictions. so you can do something like this:
$(‘output’).prop(‘value’, “”+$.prop( inputElement, ‘valueAsNumber’).replace(‘.’, ‘,’));
“output simply shows what the developer puts into”
Should the value of an output element be submitted along with all the outher form data? The specs don’t seem to address that clearly, but an output element can have a name attribute, and that seems to indicate that its value should be submitted. If so, then it does matter how decimal separators are interpreted. What should be submitted if the value “1,234” is put into an output element? And what would the valueAsNumber property be?
@Bertil – The submittable elements are button, input, keygen, object, select and textarea. So not the output element. See
http://dev.w3.org/html5/spec/forms.html#category-submit
Value “any” for “step” attribute isn’t working correctly in Safari for input type number…
39/100 is not so much the output of a computation, but the computation itself :)
I think you could make a case that the output with the range is actually the result of a division (computing percentages)
I guess should show not only “result of a calculation” but result at all! Then I see lots of cases we can use element. For example real-time updating comment preview or the preview of cropped image when you are changing your userpic.
I guess <input> should show not only “result of a calculation” but result at all! Then I see lots of cases we can use <input> element. For example real-time updating comment preview or the preview of cropped image when you are changing your userpic.
Definitely a feature for the future (hey it rhymed :))
Thanks Richard. One question, related to PHP, can the $_POST array handle the output element?
“One question, related to PHP, can the $_POST array handle the output element?”
If the value of an output element is not submitted at all (as it seems), then there is nothing to handle.
If on the other hand it does get submitted, then there is no way for PHP to tell if the value came from an output element, from an input element of from some other element (or indeed from any kind of HTML element at all). It will simply be there in the $_POST array (or $_GET array) with its name and its value. So PHP can indeed handle such submissions.
Many thanks Bertil. I don’t know why I was under the impression that the $_POST or $_GET array were conditioned by input tags that are commonly supported in HTML (radio, select, text, etc, etc) but now that I think of it, what matters is actually the name attribute for the array to recognize it.
Looking forward to some test cross browser styling with this. Good article cheers.
I just found one more tutorial where you can change the slider holder using CSS, range slider is good but the most important is the CSS customization
Here is a link of it
http://webstutorial.com/range-input-slider-html5-css3/html-5
And you have explained in a cleaned way. Thanks for the article on different HTML5 inputs
hi.. instead of output element i passed the value to text box. i need to edit textbox value but i cant.. pls help
0
100
+
=
for complex calculation I find this format useful:
<form onSubmit=”return false” oninput=”
(any number of lines of js code)
outputname.value = …
“>
How do I round the results to specific decimal points?
When dealing with $, I want only two decimal points.
I tried http://html5doctor.com/demos/output/1.html by after disabling the JavaScript and it’s not working. Does browsers internally use JavaScript to achieve intended functionality?
@Raja: Not internally: there’s JavaScript on that page that sets the value of the output element. It’s in the oninput attribute of the form element.
The output element doesn’t actually perform math for you; it simply provides a semantically meaningful place to put the results of a calculation.
Just a quick note to say that the bug report I mentioned in the post has been resolved and you can now use output for the result of a user action or calculation.
Request for Help. (thank you-in-advance, *very much*)
I’m a weekend warrior on this stuff… many things have improved since I last worked on a project (HTML5, etc).
I am trying to create a browser based GUI for a custom telnet application. When I noticed that HTM5 had support for WebSockets, well.. the chase was on.
I have a browser GUI developed and am now stuck on outputing text strings to a text area (a area on the page).
When the equipment that is telnetted to, it responds with information that I need to display dynamically. (to see the results of commands sent to the equipment).
I’ve tried (input only… when written to via the getElementById() method, the screen is cleared (no “\n” support). Same thing for the div statement and the tag. I don’t want to go to flash & activescript. I would much prefer a HTML5/Javascript solution, if there is one.
I guess I could give up and do this with perl. (no GUI and I have the functional logic mostly done… no sockets yet).
Anyone have insight to this one?
Thank you,
Rick, Denver, Coloardo.
The above post removed the ‘div’ and other tags which I have tried.
Correction: (a ‘div’ area on the page).
Correction: (Same thing for the ‘div’ statement and ‘open’ tag)
Sorry, it also clipped the ‘output’ tag.
I guess I could dynamically build a string array and feed it to the getElementById(), losing the 1st line when the # of buffered lines is overrun…. but that’s pretty tedious work. (sure, I had to struggle thru those sorting exercises, way back in the ‘c’ age).
I would think that the guru’s of HTML5 would have foreseen this necessity. I just can’t figure it out so far.
Thanks… Rick.
Hi!
Just ran the linked test page ( http://miketaylr.com/code/html5-output-element-support.html )
in IE10 ( 10.0.9200.16384 on win8 )
and it’s a complete fail, so I would update the browser support section because it is NOT working in 10!
Dr.Richard – I wanted to know as to how I would be able to display the output of form – type:range as numbers separated by commas ?
Say I set the range at $100000 – I want it to be displayed as &100,000
Please Help!
I figure that while I might use the OUTPUT element , I’ll probably still use the :before{content:attr(data-value);display:inline-block …} bit on slider type things too, as it still seems to work better for te moment.
What about using the output element for input error messages?
So something like the following
<form>
<p>
<label for=username>Username</label>
<input type=text id=username name=username required inputmode=verbatim>
<output hidden for=username role=alert>Username is already taken</output>
</p>
Could the output element be used for things besides calculation, such as letting a user know that the username is already taken (via ajax) in a website registration form?
yes
Thanks for the article! Two points:
1. In figure 5 you can also use flevel.value.
2. In figure 6 you can also use parseInt.
Join the discussion.