Form Elements - HTML reference 2026 vdsology
- Chapter 8 — Form Elements
- 8.1 — <form>
- 8.2 — <input> — All 22 Types
- 8.2.1 — type="text" — Single-Line Text
- 8.2.2 — type="email"
- 8.2.3 — type="password"
- 8.2.4 — type="number"
- 8.2.5 — type="tel"
- 8.2.6 — type="url"
- 8.2.7 — type="search"
- 8.2.8 — type="date"
- 8.2.9 — type="time"
- 8.2.10 — type="datetime-local"
- 8.2.11 — type="month"
- 8.2.12 — type="week"
- 8.2.13 — type="color" — Colour Picker
- 8.2.14 — type="range" — Slider
- 8.2.15 — type="checkbox"
- 8.2.16 — type="radio"
- 8.2.17 — type="file"
- 8.2.18 — type="hidden"
- 8.2.19–8.2.21 — type="submit", type="reset", type="button"
- 8.2.22 — type="image" — Image Submit Button
- 8.3 — Form Override Attributes
- 8.4 — command and commandfor — Invoker Commands API (cross-browser December 2025)
- 8.5 — <textarea> — Multi-Line Text
- 8.6 — <select> — Dropdown / List Box
- 8.7 — <option> and <optgroup>
- 8.8 — <datalist> — Suggestion List
- 8.9 — <selectedcontent> (New 2025 — Chrome prototyping)
- 8.10 — <button>
- 8.11 — <label>
- 8.12 — <fieldset> and <legend>
- 8.13 — <output>, <progress>, <meter>
- 8.14 — Input Attribute-by-Type Matrix
Chapter 8 — Form Elements
Forms are how HTML collects input from users.
<input>alone has 22 types, each enabling different attributes. This chapter covers every form element with every attribute, all 22 input types, thecommand/commandforInvoker Commands API,dirname,alpha/colorspaceon color inputs,<selectedcontent>, and complete validation.
8.1 — <form>
Attributes:
| Attribute | Values | Purpose |
|---|---|---|
action |
URL | Where form data is sent |
method |
get, post, dialog |
HTTP method |
enctype |
application/x-www-form-urlencoded, multipart/form-data, text/plain |
How to encode data |
name |
String | Form name |
target |
_self, _blank, _parent, _top |
Where to display response |
autocomplete |
on, off |
Default autofill for contained controls |
autocorrect |
on, off |
Autocorrection for contained controls |
novalidate |
Boolean | Disable constraint validation |
rel |
noopener, noreferrer, external |
Link relationship |
method values:
get— Appends data as query string. Use for searches, filters (idempotent requests).post— Sends data in request body. Use for creating/changing server state.dialog— Closes the parent<dialog>. Submit button’svaluebecomesdialog.returnValue.
<form action="/api/register" method="post" autocomplete="on" novalidate>
<!-- ... -->
</form>
<dialog id="confirm">
<form method="dialog">
<button type="submit" value="yes">Confirm</button>
<button type="submit" value="no">Cancel</button>
</form>
</dialog>
8.2 — <input> — All 22 Types
Shared attributes (apply to most types):
type, name, value, id, disabled, readonly, required, autofocus, form, autocomplete, autocorrect, inputmode, enterkeyhint, tabindex
8.2.1 — type="text" — Single-Line Text
Type-specific attributes: placeholder, minlength, maxlength, pattern, size, list, readonly, dirname
<label for="username">Username</label>
<input type="text" id="username" name="username"
placeholder="e.g. alice_smith"
minlength="3" maxlength="30"
pattern="[a-z0-9_]+"
autocomplete="username"
autocorrect="off"
autocapitalize="off"
required>
dirname attribute (on text, search, url, tel, email, hidden, textarea)
When included, the form submits two name/value pairs: the field’s value AND the text directionality (ltr or rtl) under the dirname value as the key.
<input type="text" name="message" dirname="message.dir" value="Hello">
<!-- Submits: message=Hello&message.dir=ltr -->
<!-- Or for RTL text: message=مرحبا&message.dir=rtl -->
8.2.2 — type="email"
Type-specific attributes: placeholder, minlength, maxlength, pattern, size, list, multiple, readonly
<input type="email" name="email" placeholder="alice@example.com"
autocomplete="email" required>
<input type="email" name="cc" multiple placeholder="a@b.com, c@d.com">
8.2.3 — type="password"
Type-specific attributes: placeholder, minlength, maxlength, pattern, size, readonly
autocorrect, spellcheck, and writing suggestions are automatically disabled.
<input type="password" name="current-password"
autocomplete="current-password" required>
<input type="password" name="new-password"
autocomplete="new-password"
minlength="8"
pattern="(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}"
required>
8.2.4 — type="number"
Type-specific attributes: min, max, step, placeholder, list, readonly
<input type="number" name="quantity" min="1" max="99" step="1" value="1" required>
<input type="number" name="price" min="0" step="0.01" placeholder="0.00">
8.2.5 — type="tel"
Type-specific attributes: placeholder, minlength, maxlength, pattern, size, list, readonly
<input type="tel" name="phone" placeholder="+44 7700 900000"
autocomplete="tel" pattern="[\d\s\+\-\(\)]{7,15}">
8.2.6 — type="url"
Type-specific attributes: placeholder, minlength, maxlength, pattern, size, list, readonly
<input type="url" name="website" placeholder="https://example.com"
autocomplete="url">
8.2.7 — type="search"
Type-specific attributes: placeholder, minlength, maxlength, pattern, size, list, readonly, dirname
<input type="search" name="q" placeholder="Search…"
enterkeyhint="search" autocomplete="off">
8.2.8 — type="date"
Type-specific attributes: min, max, step, list, readonly
step = number of days. Value format: YYYY-MM-DD.
<input type="date" name="birthdate" min="1900-01-01"
max="2026-04-26" autocomplete="bday">
8.2.9 — type="time"
Type-specific attributes: min, max, step, list, readonly
step = seconds. step="900" = 15-minute intervals. Value format: HH:MM or HH:MM:SS.
<input type="time" name="time" min="09:00" max="17:00" step="1800">
8.2.10 — type="datetime-local"
Type-specific attributes: min, max, step, list, readonly
No timezone. Value format: YYYY-MM-DDTHH:MM.
<input type="datetime-local" name="meeting"
min="2026-04-26T09:00" step="900">
8.2.11 — type="month"
Type-specific attributes: min, max, step, list, readonly
Value format: YYYY-MM.
<input type="month" name="expiry" min="2026-05" autocomplete="cc-exp">
8.2.12 — type="week"
Type-specific attributes: min, max, step, list, readonly
Value format: YYYY-Www.
<input type="week" name="sprint" min="2026-W01" max="2026-W52">
8.2.13 — type="color" — Colour Picker
Type-specific attributes: list, alpha, colorspace
alpha (Boolean — new): Enables an opacity/transparency channel in the colour picker.
colorspace (Enumerated — new): Colour space for the serialised value.
limited-srgb— Standard sRGB hex (#rrggbb). Default.display-p3— Wide-colour-gamut P3 space for HDR-capable displays.
Value format change (2026): Previously only accepted 6-digit hex (#rrggbb). Now accepts any valid CSS colour: named colours, rgb(), hsl(), oklch(), oklab(), etc.
<!-- Standard opaque colour picker -->
<input type="color" name="color" value="#2563eb">
<!-- With alpha channel (opacity slider) -->
<input type="color" name="overlay" value="rgba(37, 99, 235, 0.5)" alpha>
<!-- Wide-gamut P3 with alpha -->
<input type="color" name="bg" value="oklab(50% 0.1 0.1 / 0.5)"
colorspace="display-p3" alpha>
<!-- With preset suggestions -->
<input type="color" name="theme" list="palette">
<datalist id="palette">
<option value="#2563eb">Blue</option>
<option value="#dc2626">Red</option>
<option value="#16a34a">Green</option>
</datalist>
8.2.14 — type="range" — Slider
Type-specific attributes: min, max, step, list
<label for="volume">Volume: <output id="vol">50</output>%</label>
<input type="range" id="volume" name="volume"
min="0" max="100" step="1" value="50"
oninput="document.getElementById('vol').value = this.value">
8.2.15 — type="checkbox"
Type-specific attributes: checked, required, value
value— Submitted when checked. Default:"on"- Unchecked checkboxes are not submitted at all
<input type="checkbox" id="terms" name="terms" value="agreed" required>
<label for="terms">I agree to the Terms of Service</label>
<!-- Multiple checkboxes: same name, different values -->
<fieldset>
<legend>Interests</legend>
<label><input type="checkbox" name="interest" value="css"> CSS</label>
<label><input type="checkbox" name="interest" value="html"> HTML</label>
<label><input type="checkbox" name="interest" value="js"> JavaScript</label>
</fieldset>
8.2.16 — type="radio"
Type-specific attributes: checked, required, value
Same name → one group → only one can be selected.
<fieldset>
<legend>Preferred contact method</legend>
<label><input type="radio" name="contact" value="email" checked> Email</label>
<label><input type="radio" name="contact" value="phone"> Phone</label>
<label><input type="radio" name="contact" value="post"> Post</label>
</fieldset>
8.2.17 — type="file"
Type-specific attributes: accept, capture, multiple, required
accept: MIME types or file extensions to filter.
capture: user (front camera) or environment (rear camera) — mobile only.
<input type="file" name="avatar" accept="image/*">
<input type="file" name="docs" accept=".pdf,.docx" multiple>
<input type="file" name="photo" accept="image/*" capture="environment">
8.2.18 — type="hidden"
Type-specific attributes: value, name, dirname, autocomplete
<input type="hidden" name="csrf_token" value="a1b2c3d4e5f6">
<input type="hidden" name="user_id" value="42">
8.2.19–8.2.21 — type="submit", type="reset", type="button"
Type-specific attributes (submit/button): value, formaction, formenctype, formmethod, formnovalidate, formtarget, popovertarget, popovertargetaction, command, commandfor, name
<input type="submit" value="Save draft" formaction="/api/draft">
<input type="submit" value="Publish" formaction="/api/publish">
<input type="reset" value="Clear form">
<input type="button" value="Preview" onclick="showPreview()">
8.2.22 — type="image" — Image Submit Button
Type-specific attributes: src, alt, width, height, formaction, formenctype, formmethod, formnovalidate, formtarget
Submits click coordinates as name.x and name.y.
<input type="image" name="pos" src="/map.png"
alt="Click your location" width="600" height="400">
8.3 — Form Override Attributes
On type="submit" and type="image" inputs and <button type="submit">:
| Attribute | Overrides form’s |
|---|---|
formaction |
action |
formenctype |
enctype |
formmethod |
method |
formnovalidate |
novalidate |
formtarget |
target |
8.4 — command and commandfor — Invoker Commands API (cross-browser December 2025)
Available on <button> and <input type="button/submit/reset">. Declaratively assign behaviour to buttons without JavaScript.
commandfor: ID of the target element.
command: Action to perform.
Built-in command values:
| Command | Action | Target |
|---|---|---|
show-modal |
Opens target <dialog> as modal |
<dialog> |
close |
Closes target <dialog> |
<dialog> |
request-close |
Requests closure (fires cancel, cancellable) |
<dialog> |
show-popover |
Shows target popover | [popover] |
hide-popover |
Hides target popover | [popover] |
toggle-popover |
Toggles target popover | [popover] |
--custom-name |
Custom command (fires command event) |
Any element |
<!-- No JavaScript needed -->
<button type="button" command="show-modal" commandfor="settings-dialog">
Open Settings
</button>
<dialog id="settings-dialog">
<button type="button" command="close" commandfor="settings-dialog">Close</button>
</dialog>
<!-- Popover toggle -->
<button type="button" command="toggle-popover" commandfor="menu">
Toggle Menu
</button>
<div id="menu" popover>…</div>
<!-- Custom command -->
<button type="button" command="--rotate" commandfor="photo">Rotate</button>
<img id="photo" src="photo.jpg" alt="Rotatable">
<script>
document.getElementById('photo').addEventListener('command', (e) => {
if (e.command === '--rotate') e.target.style.rotate = '90deg';
});
</script>
8.5 — <textarea> — Multi-Line Text
Attributes:
| Attribute | Purpose |
|---|---|
name |
Submission key |
rows |
Visible height in text lines (default: 2) |
cols |
Visible width in characters (default: 20) |
placeholder |
Ghost text when empty |
required |
Boolean |
disabled |
Boolean |
readonly |
Boolean |
autofocus |
Boolean |
maxlength |
Max characters |
minlength |
Min characters |
autocomplete |
Autofill hint |
autocorrect |
on or off |
spellcheck |
true or false |
wrap |
soft (default) or hard |
form |
ID of owning form |
dirname |
Submits directionality |
Default value = text content between tags (start content immediately after <textarea>).
<label for="bio">Bio</label>
<textarea id="bio" name="bio" rows="6"
minlength="20" maxlength="500"
autocorrect="on" required></textarea>
<!-- With dirname -->
<textarea name="message" dirname="message.dir" rows="4"></textarea>
8.6 — <select> — Dropdown / List Box
Attributes:
| Attribute | Purpose |
|---|---|
name |
Submission key |
multiple |
Boolean — allow multiple selections; renders as list box |
size |
Visible options. Default: 1 (dropdown). ≥2 → list box. |
required |
Boolean |
disabled |
Boolean |
autofocus |
Boolean |
autocomplete |
Autofill hint |
form |
ID of owning form |
Direct children of <select> (content model):
<button>(first child only — for customisable select)<option><optgroup>(containing<option>)<hr>(separator line)
<select name="country" autocomplete="country" required>
<option value="">Choose a country…</option>
<option value="gb">United Kingdom</option>
<option value="us">United States</option>
</select>
<!-- Multi-select -->
<select name="skill" multiple size="6">
<option value="html">HTML</option>
<option value="css">CSS</option>
</select>
<!-- Grouped with optgroup -->
<select name="tz">
<optgroup label="Americas">
<option value="America/New_York">Eastern (UTC-5)</option>
<option value="America/Los_Angeles">Pacific (UTC-8)</option>
</optgroup>
<optgroup label="Europe">
<option value="Europe/London">London (UTC+0)</option>
</optgroup>
</select>
<!-- HR separator (cross-browser) -->
<select name="food">
<option>Apple</option>
<option>Orange</option>
<hr>
<option>Broccoli</option>
<option>Squash</option>
</select>
8.7 — <option> and <optgroup>
<option> attributes:
| Attribute | Purpose |
|---|---|
value |
Value submitted. If absent, text content is used. |
label |
Short label shown in UI |
selected |
Boolean — pre-selected |
disabled |
Boolean — cannot be chosen |
<optgroup> attributes:
| Attribute | Purpose |
|---|---|
label |
Group heading text. Required. |
disabled |
Boolean — disables all options in the group |
8.8 — <datalist> — Suggestion List
Suggestions for a linked <input>. User can type any value; suggestions are just hints.
<input type="text" name="city" list="cities">
<datalist id="cities">
<option value="London">
<option value="Paris">
<option value="Tokyo">
</datalist>
8.9 — <selectedcontent> (New 2025 — Chrome prototyping)
When placed inside a <button> that is the first child of a <select>, it acts as a live mirror of the currently selected <option>’s contents.
<select name="plan">
<button>
<selectedcontent></selectedcontent> <!-- mirrors selected option -->
<span>▼</span>
</button>
<option value="free">
<span>🆓</span> <strong>Free</strong> — 1 GB
</option>
<option value="pro" selected>
<span>⭐</span> <strong>Pro</strong> — 50 GB
</option>
</select>
8.10 — <button>
Attributes:
| Attribute | Values | Purpose |
|---|---|---|
type |
submit, button, reset |
Button behaviour (default: submit in form; submit in auto state) |
name |
String | Submission key |
value |
String | Value submitted with form |
disabled |
Boolean | Prevent interaction |
autofocus |
Boolean | Focus on page load |
form |
ID | Associated form |
formaction |
URL | Override form action |
formenctype |
Encoding | Override form encoding |
formmethod |
get, post, dialog |
Override form method |
formnovalidate |
Boolean | Skip validation |
formtarget |
Target | Override form target |
popovertarget |
ID | Popover element to control |
popovertargetaction |
toggle, show, hide |
Popover action |
command |
Command value | Invoker command |
commandfor |
ID | Target for the command |
interestfor |
ID | Hint popover on hover/focus (experimental) |
Always specify type explicitly to prevent accidental form submission.
<button type="submit">Submit</button>
<button type="button" onclick="doThing()">Action</button>
<button type="reset">Clear</button>
<!-- Rich content (not possible with <input type="button">) -->
<button type="submit">
<svg aria-hidden="true" width="20" height="20">…</svg>
<span>Save changes</span>
</button>
8.11 — <label>
Attributes:
| Attribute | Purpose |
|---|---|
for |
ID of the labelled control |
form |
ID of associated form |
<!-- Explicit association -->
<label for="email">Email address</label>
<input type="email" id="email" name="email">
<!-- Wrapping (implicit) association -->
<label>
<input type="checkbox" name="newsletter"> Subscribe to newsletter
</label>
Rules:
- Every visible interactive control needs a label
- Cannot nest
<button>,<select>,<textarea>,<meter>,<progress>,<output>, or another<label>
8.12 — <fieldset> and <legend>
<fieldset> attributes:
| Attribute | Purpose |
|---|---|
disabled |
Boolean — disables all form controls inside (except first <legend> children) |
name |
Name for JavaScript access |
form |
ID of associated form |
<legend>: No element-specific attributes. First child of <fieldset>. Contains phrasing content.
<fieldset>
<legend>Billing address</legend>
<label for="street">Street</label>
<input type="text" id="street" name="billing-street"
autocomplete="billing street-address">
<label for="city">City</label>
<input type="text" id="city" name="billing-city"
autocomplete="billing address-level2">
</fieldset>
<!-- Disabled fieldset -->
<fieldset disabled>
<legend>Payment details (free plan)</legend>
<input type="text" name="cc-number" placeholder="Card number">
</fieldset>
8.13 — <output>, <progress>, <meter>
<output> — Calculation Result
Attributes: for (space-separated input IDs), name, form
Implicit ARIA role: status
<form oninput="bmi.value=(weight.value/((height.value/100)**2)).toFixed(1)">
<label>Weight (kg): <input type="number" name="weight" id="weight" value="70"></label>
<label>Height (cm): <input type="number" name="height" id="height" value="175"></label>
<p>BMI: <output name="bmi" for="weight height">22.0</output></p>
</form>
<progress> — Progress Bar
Attributes: value (omit for indeterminate), max (default: 1)
Implicit ARIA role: progressbar
<progress value="60" max="100" aria-label="Upload progress">60%</progress>
<progress aria-label="Loading…"></progress><!-- indeterminate -->
<meter> — Scalar Gauge
Attributes: value (required), min, max, low, high, optimum, form
Implicit ARIA role: meter
Colour zones: optimal zone = green, sub-optimal = yellow, worst = red.
<label for="disk">Disk usage</label>
<meter id="disk" value="75" min="0" max="100" low="60" high="80" optimum="20">
75 of 100 GB used
</meter>
8.14 — Input Attribute-by-Type Matrix
| Attribute | text | password | number | tel | url | search | date/time | color | range | checkbox | radio | file | hidden | submit/button | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
placeholder |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | — | — | — | — |
minlength/maxlength |
✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | — | — | — | — | — | — | — | — |
pattern |
✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | — | — | — | — | — | — | — | — |
min/max |
— | — | — | ✓ | — | — | — | ✓ | — | ✓ | — | — | — | — | — |
step |
— | — | — | ✓ | — | — | — | ✓ | — | ✓ | — | — | — | — | — |
multiple |
— | ✓ | — | — | — | — | — | — | — | — | — | — | ✓ | — | — |
list |
✓ | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | — |
checked |
— | — | — | — | — | — | — | — | — | — | ✓ | ✓ | — | — | — |
accept |
— | — | — | — | — | — | — | — | — | — | — | — | ✓ | — | — |
capture |
— | — | — | — | — | — | — | — | — | — | — | — | ✓ | — | — |
readonly |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | — | — | — | — |
required |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | ✓ | ✓ | ✓ | — | — |
dirname |
✓ | ✓ | — | — | ✓ | ✓ | ✓ | — | — | — | — | — | — | ✓ | — |
alpha |
— | — | — | — | — | — | — | — | ✓ | — | — | — | — | — | — |
colorspace |
— | — | — | — | — | — | — | — | ✓ | — | — | — | — | — | — |
command/commandfor |
— | — | — | — | — | — | — | — | — | — | — | — | — | — | ✓ |
Tags: #html #vdsology #webdevelopment #vdsologyhtml #html5 #htmlreference #htmlreference2026
Write a comment