Forms That Work
Collect input with labels, useful controls, validation, and accessible feedback.
Forms connect people to an application. Native controls provide keyboard behavior, mobile input modes, validation, and accessibility semantics before any JavaScript is added.
Labels and controls
Pair every control with a visible label. Matching for and id values makes the label clickable and gives the control an accessible name.
<form action="/subscribe" method="post">
<label for="email">Email address</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<button type="submit">Join the list</button>
</form>
The name becomes the submitted field name. Pick the most specific input type so devices can offer the right keyboard and browsers can validate the format.
Group related choices
<fieldset>
<legend>Preferred study time</legend>
<label><input type="radio" name="study-time" value="morning" /> Morning</label>
<label><input type="radio" name="study-time" value="evening" /> Evening</label>
</fieldset>
Use fieldset and legend when several controls answer one question. A button inside a form submits by default, so write type="button" for buttons with a different purpose.
Validation and feedback
HTML constraints such as required, minlength, min, and pattern improve the first line of validation. The server must still validate every submitted value.
<label for="display-name">Display name</label>
<input id="display-name" name="displayName" minlength="2" maxlength="40" aria-describedby="name-help" required />
<p id="name-help">Use 2–40 characters.</p>
Keep this
Start with native controls, label everything, group related fields, choose accurate types, and validate again on the server.