HTML’s Best‑Kept Secret: the output tag

Filed in: html, accessibility, forms

Den Odell uncovers <output>, the semantic HTML element that feels like it's been hiding in the spec since 2008.

The lovely little <output> tag is mapped to role="status" and makes dynamic updates possible without ARIA workarounds. A semantic-first principle everyone advocates and it's just there waiting for us. The irony is that component-driven frameworks trained an entire generation to abstract away from HTML semantics, turning everything into divs wrapped in utility classes.

I love stumbling on posts like this—calling attention to long-standing fundamentals that have been there all along, allowing us to do what we need in an elegant, legacy-friendly, and long-established way.

The opportunities should be plentiful: it doesn’t require a <form> and you can use <output> anywhere you update text as a result of user input or app events.

Demo time#

A no-form-required example; this just updates the <output> element's text when something changes:

<output id="result">Waiting…</output>
<button type="button" id="randomize" class="kh-button">Randomize</button>
<script>
    const out = document.getElementById('result');
    const btn = document.getElementById('randomize');
    const words = [
        'bamboozle', 'flibbertigibbet', 'kerfuffle',
        'skedaddle', 'whippersnapper', 'hullabaloo', 'malarkey'
    ];
    function randomPhrase(count = 3) {
        return Array.from({ length: count }, () => (
        words[Math.floor(Math.random() * words.length)]
        )).join(' ');
    }
    function update() { out.textContent = randomPhrase(3); }
    btn.addEventListener('click', update);
    update();
</script>
Waiting…

Also worth a look: a small working example from Bob Rudis that shows a richer implementation in action.

Learn more at the source

More things I've been digesting