Widgets without JavaScript
Interaction the browser already ships: a disclosure, suggestions for an input, and progress you can see — no script required.
Interaction the browser already has
Some things that look like they need a script are built into HTML. A question that reveals its answer, an input that suggests values as you type, a bar that shows how far along something is — each has an element, and each one works with a keyboard and a screen reader before you write a line of code.
That matters beyond convenience. A native widget keeps working when a script fails to load, is faster to build, and behaves the way the platform behaves — including on a phone, in a screen reader and under keyboard control, all of which a hand-made imitation has to earn back.
A disclosure is not an accordion
<details> is one question that can open and close. The <summary> is the line always shown, and everything after it is revealed when the reader opens the element. The browser supplies the marker, the keyboard behaviour and the open state; open in the markup starts it expanded.
Several <details> elements are independent by default. Giving them the same name makes them exclusive: opening one closes the others, which is the accordion behaviour people usually build with a script. Nothing is fetched and nothing is hidden from a reader who lands on the page with a fragment link.
Four worth knowing
detailsandsummary— a disclosure. The summary is the line shown; everything else inside is revealed when it is opened.datalist— suggestions for an input. The reader may still type something else; it is a list of hints, not a dropdown that restricts.meter— a value inside a known range, like disk usage. It shows how full something is.progress— a value that is moving toward completion, like an upload. Unfinished work, not a measurement.
What the browser does for you
Each of these elements carries behaviour you would otherwise have to rebuild. A <summary> is a button that expands and collapses its parent; the browser puts it in the tab order, opens it with Enter or Space, and reports whether it is open. A <datalist> is linked to its input by id and list, and the browser shows matching options as the reader types. <meter> and <progress> expose their values to assistive technology, so a listener hears "72 percent" rather than a coloured rectangle. The element is doing the work; your markup only has to connect it. A <datalist> that is not connected by id is simply a list nobody sees.
Meter and progress answer different questions
<meter> measures something inside a known range: how full a jar is, how much disk is left, how a score sits between a minimum and a maximum. value, min and max describe the measurement, and low, high and optimum let the browser colour the result as good, average or bad without a script.
<progress> is different: it reports how far a task has got toward completion. max says what finished looks like and value says where it is now. Leave value off and the bar becomes indeterminate — the honest display for work whose remaining time nobody knows.
A question, and a hint
<details>
<summary>Can I use my own starter?</summary>
<p>Yes — feed it twice before baking day and it behaves the same.</p>
</details>
<input list="flours" name="flour" placeholder="Choose a flour">
<datalist id="flours">
<option value="White bread flour">
<option value="Wholemeal">
<option value="Rye">
</datalist>When the shape is wrong
The wrong shape is easy to spot once you know what to ask. A <details> with no <summary> gets a browser-supplied label, usually "Details", which names nothing. A <meter> whose value is outside min and max is clamped, so the display quietly disagrees with the number you meant. A <progress> with no max defaults to 1, and a value of 40 is then treated as complete rather than forty percent. Read the attributes back as a sentence: what is measured, between what bounds, and how far along it is.
Know the limits
Native widgets trade control for behaviour: the animation is the browser’s own, and some parts differ between browsers. Where HTML has no element for what you need — a date picker with rules, a multi-step form — markup has run out, and that is where a script begins.
The rule of thumb is the same as everywhere in this course: use the element that means what you mean, and only build custom behaviour where the platform genuinely has none.
Three questions, one at a time
Everything on the page is open at once. Turn each question into a details element so its answer waits to be asked for.
2 left to do
- Each question is its own details element
- The question is the summary line
Each question and answer becomes <details><summary>Question</summary><p>Answer</p></details>.
Three widget mistakes: a <details> with no <summary>, which the browser has to label for you; a <meter> used for a task that is still running, when <progress> is the honest element; and a datalist whose id does not match the input’s list, so the suggestions never appear. A native element only helps when the connection is right.
Try these next
- Give two
<details>elements the samenameand open them one after the other. - Add a
<meter>for a value between a minimum and a maximum, then move the value pasthigh. - Show an upload with
<progress>at three stages, including one with novalue.
A measurement and a task
The page reports two different things in plain text: how full the starter jar is, and how far the upload has got. Show the first with a meter inside a known range, and the second with a progress bar that has a maximum and a current value.
A <details> works without JavaScript, which makes it the safest way to write an FAQ, a spoiler, or a long settings panel that most readers never open.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What does a <details> element do without any JavaScript?
