The <output> Tag

2 days ago (denodell.com)

Problem with <output> is that it is half-baked making its usage almost useless.

It would be significantly more practical for the output to have "type" attribute in the same way as in the input.

I did experiment with oputput|type in my Sciter and added these:

   type="text" - default value, no formating
   type="number" - formats content as a number using users locale settings,
   type="currency" - formats content as a currency using users locale settings,
   type="date"  - as a date, no TZ conversion, 
   type="date-local" - as a date in users format, UTC datetime to local,
   type="time" - as a time
   type="time-local" - as a local time, value treated as UTC datetime. 

This way server can provide data without need to know users locale.

  • From the article: and spec:

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

    <output> is for changing content. It's the ARIA semantics that matter. The content gets announced after page updates.

    You can put whatever you want inside the <output> to represent the type. "text" is the default. You can represent dates and times with the <time> element. And while there is currently no specific number formatting element, since Intl has arrived there have been many requests for this.

    For example:

        <output>The new date is <time datetime="2025-10-11">Oct 11</time></output>
    

    IOW, <output> should not have to handle all these types when it handles HTML and HTML needs to represent the types anyway.

  • > half-baked making its usage almost useless.

    It's sad how many elements this is still the case for in 2025. A good chunk of them can be blamed on Safari.

    Probably the most extreme example of this is <input type="date"> which is supposedly production-ready but still has so many browser quirks that it's almost always better to use a JS date picker, which feels icky.

    • Omg yes, I thought I was crazy when I was pushing for native input type=date instead of JS date picker, it worked perfectly with minimal configuration on my phone and on my Mac, but then my coworkers said it didn't work for them on their browsers, turns out, yeah, it's not consistent.

      I then proceeded to spend the next week crying trying to get JS date picker to work as well as native did on my browsers.

      5 replies →

    • The one that gets me is the fact that there's no user-editable combobox. There's a select drop down, and "input + datalist" (and that doesn't help when there's effectively 0 hint about what the things you can use actually are), but no way to have the two combined.

      It's actually a little surprising to me since these are somewhat basic controls that have been around in UI toolkits for decades. It's in that weird sweet spot where the building blocks are almost usable enough to build rich applications, but it's just out of reach.

    • Safari and Firefox together seem to always be dragging their feet on things. Sure, sometimes it's "standards" chrome is ramming through, but many times it's things like this, that have been around since before chrome

  • You are thinking about it wrong, output is not symmetrical to input to have a type, it's a container for content that updates while you're using the page.

  • I'd prefer:

        <output for=input>
          <!-- bring your own time-locale component -->
          <time is=time-locale datetime=2001-02-03>2001-02-03</time>
        </output>
    

    With the component replacing the value dependent on locale. I don't think having HTML/CSS fiddling around with making fake content is a great idea, it already causes issues with trying to copy things injected by CSS's :before/:after psudoelements, let alone having a difference between the DOM's .innerText and, well, the inner text.

    Not saying decisions can't be made about these things, just that, making those decisions will pretty much make a dedicated DSL out of a single element (dependent on input, desired kind of output (absolute or relative), other data sent along side (type of currency, does it need to be a "real" currency? Since instead of just calling something in mutable/overridable JS, its now part of the HTML processing, something that can't directly be touched)

    • I agree in general but I think for showing a date/time in the users chosen locale I’d make an exception. Just seems a lot easier than managing that in your application.

      1 reply →

  • It's still better than <span> or <div> though, isn't it? Which is what most people are using right now...

    • Unlike <div> and <span>, <output> becomes part of the form and you can target it as a named form item, e.g.

          <form id="my-form">
            <input name="number" type="number">
            <output name="result"></output>
          </form>
      
          <script>
            const myForm = document.getElementById("my-form");
            const inputField = document.elements.namedItem("number");
            const outputField = document.elements.namedItem("result");
      
            outputField.textContent = inputField.valueAsNumber ** 2;
          </script>

      1 reply →

  • I would be on board with most of these, but...Why on earth would the server send a currency value without knowing the users locale? Are you expecting the browser to be constantly pinging services to see exchange rates?

    • !!!

      A payment, bill, price, etc has a particular currency.

      For example, 59.95 Australian dollars:

      In en-AU locale, that is $59,95.

      In en-US locale, that is 59.95 AUD or AU$59.95.

      Either way, the quantity and units are the same, but they are presented differently.

      In some cases, there may be currency exchange services. That will depend on the current exchange rate, and possibly exchange fees. And yes, that will take some more work. But that’s a fundamentally distinct concept than pure presentation of a monetary amount.

      2 replies →

    • You shouldn’t ever need to poll from the browser. If you were using WebSockets you could send 5 stock updates to the browser per second with almost no resource costs.

  • Top personal issue, be nice if it could just attach to an <input> and list the result. Like:

      <input type="range" id="example_id" name="example_nm" min="0" max="50">
      <output name="example_result" for="example_id"></output>
    

    And it would just show you the input value. Maybe with a "type" specifier like talked about. Maybe the ::before or ::after css and it would allow content: updates or something.

    Bunch of <input> types that there's a reasonable case for. Especially if it allowed for formatting. Did you put in the type="tel" the way you believed? It prints it out formatted.

    'checkbox, color, date, datetime-local, file, month, number, radio, range, tel, time, url, week' might all have possible uses. Some of the text cases might have uses in specific conditions. 'email, text, url'

    Also be nice if the for="" attribute actually did very much. The attachment seems mostly irrelevant in the examples seen. Most example just use a variation on:

      <output name="result">
      <form oninput="result.value=...">

  • It is trivial to do that with JavaScript as you fill in the content of <output> using Intt, e.g.

        const outputEl = document.getElementById("my-output");
        const currencyFormat = new Intl.NumberFormat("default", {
          style: "currency",
          currency: "ISK",
        });
    
        outputEl.textContent = currencyFormat.format(value);
    

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

    • Ok, but as a peer comment points out, doing this client-side is fraught / potentially nonsensical to convert a monetary number value to a different currency if you don't know the exchange rate.

      1 reply →

  • How is that currency one supposed to work? Converting between currencies depends on their browser picking an exchange rate that you would never want to trust if your doing anything that involves actual transactions.

    • It formats numbers and that's it, it doesn't know what currency it is and doesn't try to guess.

  • Also, if to allow form.value to accept JSON-ish objects it will be possible to set form values in single shot:

       form.value = { transAmount: 12345n, transDate: new Date() };
    

    where form is

       <form>
         ... <output type="currency" name="transAmount" />
         ... <output type="date-local" name="transDate" />
       </form>

  • That's basically the story with every browser feature. How did we get to the point that everything is built for this awful platform?

    • I think we got to this point because the browser was originally a tool to browse documents and media. Now it’s kind of a software distribution platform with interactivity. And we got there by quick implementations/workarounds.

> But <output>? Most have never touched it. Some don’t even know it exists.

Yeah, count me on with those who don't even know it exists. I'm adding this to my TIL.

> When I searched GitHub public repos, it barely showed up at all.

> That absence creates a feedback loop: if no one teaches it, no one uses it.

This has triggered an instant question in my head: Do LLMs actually use it when generating code or they are not well-trained for this specific tag?

  • I, too, am concerned about AIs not reading the docs. What happens when a new W3C spec comes out and most people are vibe coding? If AIs don't take current specs into account and just regurgitate old code patterns, then disseminating spec updates or new specs will be harder than it already is.

    • Alternate problem. I was trying to fix up an old repo I found which used some pdf tool, but when trying an LLM it insisted on reading all the documentation, but the docs were woefully out of date and didn't match the actually binaries, so it got terribly twisted up.

    • Most people don't care about W3C specs as it is, nevermind with vibe coding. The React release notes are the important web standards they follow.

      1 reply →

    • Yeah llms don’t read docs. They repeat the info in docs. And swap letters around the code to make it fit.

  • LLMs generate code based on statistical patterns found in vast amounts of training data from existing projects, not by reading language specifications. If the tag is rare in the wild, it will be rare in their output.

    • LLMs also don't know about new MCP tools when they are training but they use them perfectly fine when presented with the information about them.

      AI software development models and agents can be "taught" to go look at the official version documentation for languages via the prompt (just as one example) without needing to modify their weights.

      One call to getSpecification('Python','3.14') or some similar tool call and they know exactly what they are working with, even if the language version did not exist when the model was trained.

    • I mean, they're trained on specs, too. I'll have to play with asking for semantic HTML and see what they come up with.

As a screen reader user, I think aria live regions (and hence the output tag) were actually a mistake.

What we should have had instead is a `document.speak(text, priority)` method, which would just pass the text straight through to the screen reader.

Sure, that approach is less pure, yet it is far more pragmatist and practical, as you only need aria when you heavily use js anyway.

Aria live regions, as they currently stand, basically encourage three anti-patterns:

First is the "if it changes, it should be announced" anti-pattern, think e.g. a constantly changing stock ticker on a news website. People make these into aria live regions because "it's live, we want to be good citizens and do semantics, right?". Sites that do this are almost impossible to use, as you're constantly distracted by the ticker. Another instance of this are timers that change every second. With a `document.speak` method, it would be far more obvious that you don't want the screen reader to announce the ticker every time it changes.

The second anti-pattern is the one of outputting the same message twice. Think a calculator where the user executes two different expressions which both produce a result of 0. The result of the second expression won't be announced, as there will be no change to the live region contents. With `document.speak`, this wouldn't be a problem, as the method would just be executed twice.

The third anti-pattern is actually somewhat specific to the `output` tag. It's very tempting to use it for terminal, log and chat outputs, and that is a mistake. Those processes append to the output instead of replacing it, but with the aria status of atomic, the entire output area would be announced every time the output changes.

> Update 7 Oct 2025: Some screen readers have been found not to announce updates to the tag, so explicitly emphasising the role attribute might be worthwhile for now until support improves: <output role="status">.

Waiting for support to improve on a 17 year old tag that is barely used anymore?

  • To improve the usage of screen readers that don’t respect a tag that’s parts of the standard for 17 years.

    It’s obviously the screen readers’ fault.

    • If adding the ARIA role fixes the problem, then it's not the fault of screen readers: it's browsers not exposing the semantics properly (unless explicitly instructed to). Please don't assign blame to the "obvious" target unless you actually know who's at fault.

      5 replies →

Semantic html is a novice trap, just do the thing that works and that browsers expect (aria-live)

It's fun to play around with things like this, but if you're a developer you have a responsibility to build things that work for your users using the existing tools and ecosystem. Don't use semantic HTML tags that aren't widely used, just do the thing that works.

  • In the article:

    > And because it has been part of the spec since 2008, support is excellent across browsers and screen readers. It also plays nicely with any JavaScript framework you might be using, like React or Vue.

    So what makes you think this isn’t a “thing that works”?

    • > Update 7 Oct 2025: Some screen readers have been found not to announce updates to the tag

  • > Semantic html is a novice trap, just do the thing that works and that browsers expect (aria-live)

    html isn't just "browsers". I've been doing alot of epub work, and semantic pages make everything easier and better.

> Like <label>, <output> has a for="" attribute. Here you list the ids of any <input> elements the result depends on

Any screen reader users able to comment on whether this is worth doing? I suspect this would be such a rarity online that screen reader users wouldn’t be familiar with it, but it depends on the UX of the software

  • Not a screen reader user but I have used them a lot in testing. I'd be surprised if it's meaningfully exposed to assistive tech. Not at the computer right now so I can't test.

    That said, I imagine it's more useful to do the opposite, label the output itself e.g.

    <label for="output">Total</label> <output id="output">£123.45</output>

    That way it will be announced like "Total, £123.45" rather than a random number with no context

    • For static scenarios this works well with screen readers. On the output tag the "for" property helps screen readers deal with dynamic values, essentially adding reactivity to the element. I use it so infrequently I've never explored how it works but screen readers will catch that the value has been updated.

      This is handy for testing with screen readers, and includes links to the appropriate spec (for output and all elements):

      https://stevefaulkner.github.io/AT-browser-tests/test-files/...

      1 reply →

I have completed multiple courses on front-end web accessibility and never run into <output>, somehow. Thanks so much for the awesome share.

I came to this article expecting to see <output> misused, and was pleasantly surprised. :-)

(Actually, the dodgy GenAI calculator image at the top primed me for even more failure, making the excellent content that followed even more surprising. But I soon forgot about it and only remembered when I scrolled back to the start for no particular reason when done.)

  • This dodgy GenAI calculator is funny... You can only add, multiply and divide. No subtractions allowed!

  • > the dodgy GenAI calculator image

    It appears human beings are already forgetting the even more dodgy images some of us created before AI allowed us to reduce said dodginess. Or actually get a picture we could post without too much shame. :)

    And in this case, IMHO, the image has a significant amount of dodgy vintage tech charm.

    Not every use of AI replaces a professional artist.

Apparently, it's about screen reader support in web pages.

Also "ARIA" stands for Accessible Rich Internet Applications and it's "a set of HTML attributes that make web content more accessible to people with disabilities."

  • This is like explaining what JavaScript is under a post about React. There’s no shame in not knowing accessibility basics, but there’s also no need to act like it’s ridiculous to expect the reader to know some.

    • I think "act like it's ridiculous" is pretty hyperbolic here. I didn't know what ARIA stood for until now (though I knew what it was).

      You'd be surprised how many people barely know it exists... I was a TA for my uni's Web Engineering and Ethics in CS courses and accessibility never even came up in either course.

      10 replies →

  • MDN has decent docs on this, including (and echoed by the author) this top-level guidance:

    >> The first rule of ARIA use is "If you can use a native HTML element or attribute with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so."

    https://developer.mozilla.org/en-US/docs/Web/Accessibility/A...

  • Hey thanks for clarifying. I could have googled it, but lazily reading your comment on a cloudy Saturday afternoon is easier. Thanks again, appreciate it. ;)

If you have to use `role=status` to make it work with screenreaders, I'm not sure I see the point.

Maybe I'm jaded, I was all in on semantic xhtml and microformats before we got HTML5, but this seems like being overly-pedantic for the sake of pedantry rather than for a11y.

  • Chicken-and-egg. As soon as more websites start using the tag, screenreaders will catch up and role=status will not be needed.

So there's useful html tags from 2008 that no one uses or knows about... How can that be the case? Because there's just so many tags? Because people don't read the docs? Because the benefits are not obvious?

  • Most sites today are not using HTML in the way it was originally envisioned. They use something called "DHTML" instead. The D stands for DIV, because people seldom use any other tag. E.g. in normal HTML you would use the TABLE, TR and TD tags to build a table. In modern DHTML (aka DIV-HTML) people build the table from fixed size DIVs, and calculate the column sizes via JavaScript.

  • Because a lot of web frontend developers are addicted to <div> soup and fancy CSS and JavaScript libraries.

    • It's also due to browser not doing anything useful with the additional tags, if I use <article>, <section> or <div> doesn't make any difference, my browser doesn't use that to generate a TOC or let me open an <article> in a new Tab. Even the, in theory, incredible useful <time> tag seems to be completely invisible to my browser and many other potentialy useful tags don't exist in the first place (e.g. <unit> would be useful).

      15 replies →

  • Because no one cares about HTML except as a payload carrier for the real website: the JavaScript output from React/Tailwind/Typescript compilation.

    You have to remember, this is an industry that thinks having code without syntax errors was too unreasonable a requirement for XHTML, there is no reason to expect them to know anything beyond div and maybe a dozen other tags.

  • For anybody wondering, there are 112 of them:

        a
        abbr
        address
        area
        article
        aside
        audio
        b
        base
        bdi
        bdo
        blockquote
        body
        br
        button
        canvas
        caption
        cite
        code
        col
        colgroup
        data
        datalist
        dd
        del
        details
        dfn
        dialog
        div
        dl
        dt
        em
        embed
        fieldset
        figcaption
        figure
        footer
        form
        h1
        h2
        h3
        h4
        h5
        h6
        head
        header
        hgroup
        hr
        html
        i
        iframe
        img
        input
        ins
        kbd
        label
        legend
        li
        link
        main
        map
        mark
        menu
        meta
        meter
        nav
        noscript
        object
        ol
        optgroup
        option
        output
        p
        picture
        pre
        progress
        q
        rp
        rt
        ruby
        s
        samp
        script
        search
        section
        select
        slot
        small
        source
        span
        strong
        style
        sub
        summary
        sup
        table
        tbody
        td
        template
        textarea
        tfoot
        th
        thead
        time
        title
        tr
        track
        u
        ul
        var
        video
        wbr

  • My guess would be that most people just copy (mimic) what is already there. I sometimes work as a freelance web administrator and I can assure you 95% of people who create websites for a living have never read through a list of HTML tags, have only a slight idea of the semantic web and in the end they are more like people who cobble existing things together and are out of their depth pretty quickly.

    Not that this is problematic per se, everybodies milage may vary and we're all out there to learn. But if I told one of them about the output tag thry probably wouldn't even understand why that would be important.

  • Maybe because most HTML tags are not well supported by browsers, because they are doing by themselves only half of what a developer would want, hard to style, hard to enhance the native behavior, ... most recently-added tags have those problems (ex: <progress>), this one from 2008 is an even better example

    • please elaborate, how is <output> a better example for only doing half of what a developer would want? what is missing?

  • > Update 7 Oct 2025: Some screen readers have been found not to announce updates to the tag, so explicitly emphasising the role attribute might be worthwhile for now until support improves: <output role="status">.

    Maybe it's because like most things html/css related, it's a semi-broken implementation of a half-feature?

  • In some cases, because there was a period of time where it might not have been in HTML in all browsers, and javascript was used instead, and then HTML had it.

    Then no one checked, and the javascript train had already left the station.

  • People who already have a habit of solving a problem a specific way are generally unlikely to switch when a new solution appears unless it is considerably easier. If it's not immediately easier, it will feel easier to continue the ingrained habit.

  • I mean with modern javascript/dom manipulation tools the only tag you really need is div.

    In before comments - not advocating for div only development, just that the nature of www moved from html with some js to well ... only js.

It’s nice seeing stuff like this.

Another is structuring your form names to help align with how it’s going to be used in the backend so you don’t have to use JavaScript to gather all the data or be doing a lot of restructuring of the request data.

This is an oversimplified example but now even if you submit with JS, you just have to submit the form and the form data is already there.

<input name=“entity[id]”>

<input name=“entity[relation]”>

For a website speaking accessibility, it does something very bad and annoying with scrolling. Not using the native browser scrolling I think. When I use the middle wheel of my mouse to go up or down, sometimes it suddenly it ignore the command or stutter or go back a little bit instead of continue going down or some random movement. Even with using 2 fingers scroll with the touchpad, I can feel very slightly that there a subtle lag or stutter.

Hell html in 2025 feels so underdeveloped, semantic html should just be declared dead and we should just move on. How many years we wasted by having "experts" underlining the semantic meaning of aside, article, main etc? Good lord, perhaps we should just totally skip the dom and use a graphics, input and accessibility api the way we want

  • It seems to me that most semantic HTML has helped third parties extract data from web pages for their own use. Perhaps if you are an important primary source of information like a government service that could be useful if it helps you advance your cause of sharing data, but I don’t think it is in the interest of most website operators if it reduces traffic to your site.

    I understand that their are some accessibility benefits to some semantic HTML tags.

    • The discussion of past years instead of being focused on "what we could do next to make developing apps for the web better?" has been focused on which semantic meaning the x tag has and where it should be used, creating just a lot of confusion and disagreements, vs the reality: people just use divs, you can still specify aria attributes there, why not giving us an api to specify semantic meaning as well the way we want? I'd like to have something like flash back, html5 was a step back, partially has already been achieved by flutter and react native. Please Browser vendors just give us a goddman drawing api that doesn't feel limited as canvas is with a semantic, accessibility and input apis that don't suck!

      3 replies →

Interestingly I've often seen this in Claude outputs, especially on long prompts. I've assumed this is because of Claude's XML-based instruction format, but this does make me wonder how related the two are. And if Claude may have a harder time using <output> given it's related to both accessibility and its instructions

I don't think this was ignored for no reason or simply forgotten. I don't see it bringing a great feature or value compared to input tag. You still need to code up the logic for setting its value, via a script, like any other container tags. You could pretty much use a read-only input tag to include the output with the form.

  • > You could pretty much use a read-only input tag to include the output with the form.

    You could, but then you wouldn't be gaining any of the accessibility wins the article is discussing...

I can see this having extreme value 20 years ago. Then it could take more than a minute to asynchronously get data back and you needed to tell people what content on the page changed.

Now, the bottleneck is entirely the database first and the framework second. Those can be switched if the framework code is extra garbage. When those are taken out of the equation I am seeing text update to the screen in about 5-15ms in response to a user interaction that requires execution on the localhost server, 45ms for networked server.

At that speed you don’t need to alert the user of any content changes. You only need to structure the content such that walking the DOM, using a screen reader, from point of interaction to area of output is direct and logical, expected, for a human.

I think the lesson here is if you want to provide an accessibility feature, you have to also make it do something useful for people that don't care about accessibility.

The article was all good until he started to use react for implementation. I would not have done that for an article about web standards, and I use react all the time.

I have no idea if it was based on the HTML tag, but ColdFusion/CFML has (always?) had the <cfoutput> tag for displaying and parsing dynamic data.

> dynamic results that are announced to screen readers by default.

> It’s been in the spec for years. Yet it’s hiding in plain sight.

Almost as if we're... blind to it?

No? Too on the nose?

I honestly don't know what is it for. Why is it important to have an output tag.

The output of any actions will be shoved into any N random elements. So every `<div>` will have `<output>`? Why? Waste of payload size and CPU cycles in parsing.

The designers of semantic tags truly live in ivory towers.

Imagine a world where you don't have to deal with legacy js, css and html stuff and you could opt-in for an alternative, better solution that just works on every single computer, the very same way it works on your own.

Imagine you place a textfield in precise spot on a screen, with your choice of font and it renders the way it renders on your screen on every client device, everywhere.

Oh wait, we had, it was called Flash.