4.0 Form Structure
An HTML form is a collection of controls that gathers user input and submits it to
a server or handles it with JavaScript. The <form> element is the
container; every control inside it participates in submission.
<form id="signup" action="/submit" method="post">
<label for="name">Name</label>
<input type="text" id="name" name="name" required>
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
<button type="submit">Sign Up</button>
</form>
The two most important <form> attributes:
-
action — URL the form data is sent to on submission.
Omit (or set to
"") when JavaScript handles submission.
-
method —
get appends data to the URL as a
query string; post sends it in the request body. Use
post for anything sensitive or large.
4.1 Labels, Fieldsets, and Legends
Associating a <label> with a control via its for
attribute (matching the control's id) improves usability: clicking the
label focuses the control, and screen readers announce the label text.
<fieldset>
<legend>Shipping Address</legend>
<label for="street">Street</label>
<input type="text" id="street" name="street">
<label for="city">City</label>
<input type="text" id="city" name="city">
</fieldset>
<fieldset> visually groups related controls; <legend>
labels the group. Both improve accessibility and structure.
4.2 Input Types
The type attribute on <input> selects both the control
widget and the validation behavior. The browser renders the appropriate UI and rejects
values that don't match the type.
Input Type Reference
| type= |
Behavior and notes |
text | Single-line free text (default when type is omitted). |
password | Masked text; value is not shown. |
email | Validates a basic email address format. |
url | Validates a URL. |
tel | Phone number; no format validation, but mobile keyboards show dialpad. |
number | Numeric spinner; accepts min, max, step. |
range | Slider between min and max. |
date | Calendar date picker (YYYY-MM-DD). |
time | Time picker (HH:MM). |
datetime-local | Date and time combined, without timezone. |
month | Year and month picker. |
week | Year and ISO week number picker. |
color | Color picker; value is a hex color string. |
checkbox | Toggle; submitted only when checked. |
radio | One choice from a group sharing the same name. |
file | File chooser; add multiple for multi-file select. |
hidden | Not shown; sends a name/value pair silently. |
submit | Button that submits the form. |
reset | Button that resets all controls to their initial values. |
button | Generic button with no default behavior; wire with JavaScript. |
image | Graphical submit button using an image source. |
search | Search field; may show a clear button in some browsers. |
Other controls complement <input>:
-
<textarea> — multi-line text with
rows and cols sizing.
-
<select> — dropdown list of
<option> elements; add multiple for a list box.
-
<datalist> — provides autocomplete
suggestions for a linked <input> via the list
attribute.
-
<button> — more flexible than
<input type="button">; its body can contain markup.
-
<output> — displays a computed result,
linked to source controls via for.
4.3 Constraint Validation
The browser validates form controls automatically before submission when constraint
attributes are present. Validation fails silently until the user tries to submit; the
browser then shows native error tooltips and blocks the request.
Constraint Attributes
| Attribute |
Effect |
required | Value must be non-empty before submission. |
minlength | Minimum number of characters for text-like inputs. |
maxlength | Maximum number of characters; also truncates paste. |
min | Minimum numeric or date value. |
max | Maximum numeric or date value. |
step | Granularity for numeric and date inputs. |
pattern | ECMAScript regex the entire value must match. |
type | Implicitly constrains format (email, url, number, etc.). |
To validate programmatically before submission, use the Constraint Validation API:
const form = document.querySelector('#signup');
form.addEventListener('submit', (e) => {
if (!form.checkValidity()) {
e.preventDefault();
form.reportValidity(); // show native tooltips
return;
}
// proceed with valid data
});
Individual controls expose validity (a ValidityState object),
validationMessage, and setCustomValidity(msg) for custom error
text.
4.4 Form Submission
The default submit action navigates the page to the action URL. JavaScript
intercepts it with preventDefault() and then sends data with
fetch. FormData collects all named control values automatically.
form.addEventListener('submit', async (e) => {
e.preventDefault();
const data = new FormData(form); // collects all name/value pairs
const resp = await fetch('/api/signup', {
method: 'POST',
body: data
});
if (resp.ok) {
console.log('submitted successfully');
}
});
FormData also lets you read or modify values before sending:
data.get('email'); // read a value
data.set('name', 'Alice'); // override a value
data.append('tag', 'web'); // add an extra key/value
To send JSON instead of multipart form data, convert FormData to a plain
object and serialize it:
const body = JSON.stringify(Object.fromEntries(data));
const resp = await fetch('/api/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body
});
4.5 Form Element Reference
Form Elements
| Element |
Purpose |
Key Attributes |
<form> | Form container | action, method, enctype, novalidate |
<input> | Single-value control | type, name, value, placeholder, required, disabled, readonly |
<textarea> | Multi-line text | name, rows, cols, maxlength, placeholder |
<select> | Dropdown or list box | name, multiple, size |
<option> | Choice in select | value, selected, disabled |
<optgroup> | Group of options | label, disabled |
<datalist> | Autocomplete source | id (linked via input list) |
<button> | Clickable button | type (submit/reset/button), name, value, disabled |
<label> | Control label | for (matches control id) |
<fieldset> | Control group | disabled (disables all children) |
<legend> | Fieldset caption | — |
<output> | Computed result | for, name |
<progress> | Completion bar | value, max |
<meter> | Scalar gauge | value, min, max, low, high, optimum |
4.6 Tutorials
HTML Forms Tutorials
| Tutorial |
Type |
Why Use It |
| MDN: Web Forms |
Beginner→Advanced |
Complete series covering structure, styling, validation, and custom controls. |
| web.dev: Learn Forms |
Intermediate |
Deep dive into accessible, robust forms from the Chrome team. |
| w3schools HTML Forms |
Beginner |
Quick reference with interactive examples for each input type. |
| MDN: Constraint Validation |
Intermediate |
Full documentation of the Constraint Validation API. |
| web.dev: Autofill |
Practical |
How to use autocomplete attributes for better UX and password managers. |
| WebAIM: Accessible Forms |
Accessibility |
Labeling, grouping, and error handling for screen readers. |
4.7 References
HTML Forms References