The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Neutral button<button type="button">Preview</button>View examples
Submit button<button type="submit">Save</button>View examples
Reset button<button type="reset">Reset</button>View examples
Disable a control<button type="button" disabled>Unavailable</button>View examples
Associate with another form<button type="submit" form="profile"> Save profile </button>View examples
Single select<select name="region"> <option value="sa">South America</option> </select>View examples
Multiple select<select name="roles" multiple> <option>Editor</option> </select>View examples
Group options<optgroup label="Americas"> <option value="br">Brazil</option> </optgroup>View examples
Known progress<progress value="65" max="100">65%</progress>View examples
Unknown progress<progress>Loading</progress>View examples
Scalar measurement<meter min="0" max="100" low="30" high="80" optimum="90" value="72"> 72 </meter>View examples
Calculation output<output for="price quantity" name="total">0</output>View examples

Native controls bring keyboard behavior, form integration, and accessibility semantics that custom widgets must rebuild. State the button type, label every control, use disabled only when interaction truly must stop, and select meter or progress according to what the value means.

Step by step

Detailed examples

01

Always choose a button type

Inside a form, a button defaults to submit. Set type=button for client-side actions and type=submit only for intentional submission. Button content can provide a rich accessible label; icon-only buttons still need an accessible name.

Separate preview from submission
<form id="draft">
  <label>Title <input name="title"></label>
  <button type="button" id="preview">Preview</button>
  <button type="submit">Publish</button>
</form>
Back to quick reference ↑
02

Model availability without hiding intent

disabled removes a control from focus and form submission; explanatory text should say why it is unavailable. readonly applies only to certain form controls and remains focusable. The form attribute can associate a button or supported control with a form outside its ancestry.

External submit with explanation
<form id="profile"><label>Name <input name="name" required></label></form>
<p id="save-help">Completes the profile.</p>
<button type="submit" form="profile" aria-describedby="save-help">Save profile</button>
Back to quick reference ↑
03

Give every option a stable submitted value

A select needs a label and name. Option text is shown to users; value is submitted, defaulting to text when omitted. multiple changes the interaction and submitted cardinality, so explain it and consider checkboxes when choices need to remain visible.

Grouped region selector
<label for="country">Country</label>
<select id="country" name="country" required>
  <option value="">Choose one</option>
  <optgroup label="Americas"><option value="br">Brazil</option><option value="ca">Canada</option></optgroup>
</select>
Back to quick reference ↑
04

Distinguish task progress from a measurement

progress shows how much of a task is complete; omit value for an indeterminate task. meter shows a scalar within a range, such as storage or a score, and its low/high/optimum thresholds provide context. Supply nearby text because visual rendering varies.

Upload progress and storage use
<label for="upload">Upload</label>
<progress id="upload" value="65" max="100">65%</progress>
<label for="storage">Storage used</label>
<meter id="storage" min="0" max="100" high="85" value="72">72%</meter>
Back to quick reference ↑
05

Expose calculated results as output

output represents a calculation result and can be named for form submission. for is a space-separated list of contributing control IDs, not a substitute for a visible description. Update textContent when values change and repeat important units in the rendered result.

Quantity total
<form id="order">
  <label>Price <input id="price" type="number" value="10"></label>
  <label>Quantity <input id="quantity" type="number" value="2"></label>
  <p>Total: <output id="total" for="price quantity">20</output></p>
</form>
<script>
  order.addEventListener('input', () => { total.value = Number(price.value) * Number(quantity.value); });
</script>
Back to quick reference ↑

Local code tester

Try native controls

Change selection, progress, and calculated output using native form semantics.

Runs in your browser
Preview

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. WHATWGHTML: The button elementhtml.spec.whatwg.org
  2. WHATWGHTML: The select elementhtml.spec.whatwg.org
  3. WHATWGHTML: The output, progress, and meter elementshtml.spec.whatwg.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback