Contents
Form basics
HTML forms are how users send data to a server. The <form> element wraps all inputs and defines where and how data is sent:
<form action="/submit" method="POST">
<label for="name">Full name</label>
<input type="text" id="name" name="name" required>
<button type="submit">Submit</button>
</form>
action is the URL that receives the data. method is either GET (data in URL) or POST (data in request body). Use POST for sensitive data.
Input types
HTML5 added many input types that provide built-in UI and validation โ use them instead of text inputs with JavaScript validation:
type="email"โ validates email format, shows email keyboard on mobiletype="tel"โ shows numeric keyboard on mobiletype="number"โ restricts to numbers, shows spinnertype="date"โ shows native date pickertype="url"โ validates URL formattype="password"โ masks inputtype="range"โ shows a slidertype="color"โ shows color pickertype="file"โ file upload buttontype="checkbox"/type="radio"โ multiple/single selection
Built-in validation
HTML5 validation attributes save you from writing JavaScript for common checks:
<input type="email" required> <!-- Must be filled, valid email -->
<input type="text" minlength="3" maxlength="50"> <!-- Length range -->
<input type="number" min="1" max="100" step="1"> <!-- Numeric range -->
<input type="text" pattern="[A-Za-z]{3,}"> <!-- Regex pattern -->
<input type="url" placeholder="https://"> <!-- URL required -->
Labels and fieldsets
Every input needs a <label>. The for attribute must match the input's id:
<label for="email">Email address</label>
<input type="email" id="email" name="email">
<!-- Group related inputs with fieldset -->
<fieldset>
<legend>Delivery address</legend>
<label for="city">City</label>
<input type="text" id="city" name="city">
<label for="zip">ZIP code</label>
<input type="text" id="zip" name="zip">
</fieldset>
Styling forms with CSS
Forms are notoriously difficult to style consistently. Key rules:
- Set
font: inheriton all inputs โ they don't inherit by default - Use
box-sizing: border-boxto make width predictable - Style
:focusstates โ never setoutline: nonewithout a replacement - Use
::placeholderto style placeholder text
Form security
- Always use HTTPS for forms that collect any user data
- Set
autocomplete="off"on sensitive fields like CVV numbers - Use CSRF tokens for state-changing POST requests
- Validate and sanitise all input server-side โ HTML validation is for UX, not security
- Use
rel="noopener noreferrer"on any<a target="_blank">links in forms