A <form> declares an interactive region whose controls submit data to a server endpoint or participate in client scripts.
Core attributes
action: URL accepting submissions (defaults to current document).method:get(idempotent queries, bookmarkable) vspost(body payloads, mutations).enctype: defaults toapplication/x-www-form-urlencoded; switch tomultipart/form-datafor file inputs.autocomplete: hints for browser password managers and form fillers.novalidate: disables native constraint validation when you supply bespoke validation UX.target: opens responses in new browsing contexts—pair carefully with security (relon submit buttons).
<form action="/search" method="get" role="search">
<label for="q">Search</label>
<input id="q" name="q" type="search" autocomplete="off">
<button type="submit">Search</button>
</form>
Rendered output
The button is type="button" so this lesson page does not submit a real GET. In production search UIs, use type="submit" on the primary action.
GET vs POST
- GET appends
name=valuepairs to the query string—subject to length limits and logging. - POST sends fields in the request body—appropriate for large payloads, file uploads, or sensitive data (still require HTTPS).
Security baseline
- Generate CSRF tokens server-side for authenticated mutations.
- Validate every field again on the server—never trust client-side checks alone.
- Use appropriate
autocompletetokens for credentials and PII handling.
What even senior teams forget
- Method semantics: GET requests should be safe/idempotent—don’t mutate databases on GET even if bots can hit URLs.
- CSRF aside:
samesitecookies help but do not replace explicit tokens when requirements demand defense in depth. - Autocomplete off isn’t privacy: it frustrates legitimate password managers—use precise tokens (
one-time-code, billing scopes) rather than blastingautocomplete="off"everywhere. - multipart boundaries: missing
enctypeon file uploads silently drops binaries—classic production support ticket starter.
Submission UX realities
- Disable submit while in-flight—but re-enable on network errors so users retry.
- Preserve scroll position after server validation errors—jumping users to tops of long forms feels broken.
- Double submits: optimistic UI ≠ duplicate charges—idempotency keys belong server-side.
Accessibility test script (forms)
- Tab path check: press Tab through the rendered form demo and confirm order is label field then button, without traps.
- Expected screen reader phrase: your SR should announce the input as “Search, edit text” (or equivalent), proving label association.
- 200% zoom check: at 200% zoom, input and submit button should remain fully visible and usable without horizontal clipping.
Important interview questions and answers
- Q: Why are native form controls preferred over custom div-based widgets?
A: They provide built-in semantics, keyboard support, validation hooks, and accessibility behavior. - Q: What does `name` do on form fields?
A: It determines the key sent in form submission payloads; without `name`, values are typically not submitted. - Q: When should you use `type="button"` instead of default buttons in forms?
A: Use `type="button"` for non-submit actions to avoid accidental form submission.
Challenge
Label every control
- Wrap each input in
<label>or usefor/id. - Mark one field
requiredand addautocompletewhere appropriate.
Done when: clicking each label focuses its field.
Interview prep
- Why must inputs have associated labels?
Labels enlarge click targets, tie accessible names to controls, and are required for screen-reader users—not just visual layout.
- What does <code>method="post"</code> imply?
The browser sends form fields in the request body, suitable for mutations; GET appends data to the URL and should be idempotent reads.