Users make mistakes: they leave fields empty, mistype an email address, enter a phone number with letters in it or choose a date in the past. Catching those mistakes before a form is sent saves everyone time. HTML can do much of this checking by itself, with no JavaScript, using validation attributes.
When a field has a rule such as required or minlength="8", the browser refuses to submit the form until the rule is met, shows a message next to the first problem and moves focus to it. Input types help too: a type="email" field already checks for an @, and type="number" rejects text. You can then style valid and invalid fields with CSS so users see problems clearly.
Browser validation improves the experience, but it is not security. Anyone can switch it off or send data directly to your server, so the server must always validate again. In this lesson you'll learn the validation attributes, the main form attributes such as action, method and autocomplete, and how to write helpful error hints.
Validation attributes
| Attribute | Rule | Example |
|---|---|---|
required | Field can't be empty | <input required> |
minlength, maxlength | Length of text | minlength="8" |
min, max | Smallest and largest number or date | min="1" max="10" |
step | Allowed increments | step="0.01" for prices |
pattern | Text must match a regular expression | pattern="[A-Z]{2}[0-9]{4}" |
type | Format such as email, url or number | type="email" |
Add a title or a hint below the field to explain a pattern, because the default error message can't describe your format.
Form attributes
actionis the URL that receives the data;methodisget(data in the URL, good for searches) orpost(data in the request body, for anything that changes something, or contains personal data).autocompletehelps browsers fill in saved details:autocomplete="email","name","street-address","current-password","new-password".novalidateon the form turns off browser validation, used when JavaScript shows its own messages.readonlyshows a value that can't be edited but is still sent;disabledfields are neither editable nor sent.autofocusplaces the cursor in a field when the page loads; use it sparingly.
Styling valid and invalid fields
CSS can react to validation:
input:user-invalid { border-color: crimson; }
input:user-valid { border-color: seagreen; }:user-invalid only applies after the user has interacted with the field, so a fresh form isn't covered in red. Older code uses :invalid, which matches immediately. Pair colour with text, such as an error message, because colour alone isn't enough for everyone.
HTML Form Validation Syntax
Validation syntax
<form action="/register" method="post">
<input type="email" name="email" required autocomplete="email">
<input type="password" name="password" required minlength="8" autocomplete="new-password">
<input type="number" name="age" min="13" max="120">
<input type="text" name="postcode" pattern="[A-Za-z0-9 ]{5,8}" title="5 to 8 letters and numbers">
<input type="number" name="price" step="0.01" min="0">
<button type="submit">Register</button>
</form>HTML Form Validation Summary
required,minlength,maxlength,min,max,stepandpatternadd built-in validation.- The browser blocks submission and highlights the first invalid field.
actionandmethoddecide where and how data is sent;autocompletespeeds up filling in.- Style feedback with
:user-invalidand:user-valid, plus clear text hints. - Client-side validation is for convenience; always validate again on the server.
HTML Form Validation Examples
Each example runs in the page. Edit the code and press Run to see what changes.
A registration form with validation
Press Register with empty or invalid fields to see the browser's checks.
<form action="#" method="post">
<p>
<label for="em">Email</label><br>
<input id="em" name="email" type="email" required autocomplete="email">
</p>
<p>
<label for="pw">Password</label><br>
<input id="pw" name="password" type="password" required minlength="8" autocomplete="new-password" aria-describedby="pw-hint">
<br><small id="pw-hint">At least 8 characters.</small>
</p>
<p>
<label for="age">Age</label><br>
<input id="age" name="age" type="number" min="13" max="120">
</p>
<button type="submit">Register</button>
</form>Line-by-line explanation
- Line 4
type="email"andrequiredtogether check that a valid address was entered. - Line 8
minlengthenforces at least 8 characters, andaria-describedbylinks the hint to the field. - Line 9The hint is visible before the user types.
- Line 13Ages outside 13 to 120 are rejected.
Patterns with helpful hints
<form action="#">
<label for="code">Discount code</label><br>
<input id="code" name="code" pattern="[A-Z]{4}[0-9]{2}" title="4 capital letters then 2 numbers, like SAVE10" placeholder="SAVE10" required>
<p><small>Format: 4 capital letters then 2 numbers.</small></p>
<label for="qty">Quantity (1 to 5)</label><br>
<input id="qty" name="qty" type="number" min="1" max="5" step="1" value="1">
<p><button type="submit">Apply</button></p>
</form>Line-by-line explanation
- Line 3
patternrequires exactly four capital letters followed by two digits. - Line 3
titleis added to the browser's error message to explain the format. - Line 6
min,maxandsteprestrict quantity to whole numbers from 1 to 5.
Styling feedback after typing
<style>
input { padding: 8px; border: 2px solid #9ca3af; border-radius: 6px; }
input:user-invalid { border-color: #dc2626; }
input:user-valid { border-color: #16a34a; }
input:user-invalid + .msg { display: block; }
.msg { display: none; color: #b91c1c; font-size: 0.9em; }
</style>
<form>
<label for="mail">Email</label><br>
<input id="mail" type="email" required>
<span class="msg">Please enter an email address like name@example.com.</span>
</form>Line-by-line explanation
- Line 3Red border once the user has typed something invalid and left the field.
- Line 4Green border when the value is valid.
- Lines 5 to 6The written message appears only when the field is invalid.
Common HTML Form Validation Mistakes
Trusting browser validation on the server
<!-- "The form has required, so the server doesn't need to check" -->
<input name="email" type="email" required><input name="email" type="email" required>
<!-- and the server validates the email again before saving -->Validation in the browser can be bypassed easily.
A pattern with no explanation
<input name="ref" pattern="[0-9]{6}"><label for="ref">Order reference (6 digits)</label>
<input id="ref" name="ref" pattern="[0-9]{6}" title="6 digits, for example 104233">Otherwise users only see "Please match the requested format".
Sending passwords with GET
<form action="/login" method="get"><form action="/login" method="post">GET puts the data in the URL, where it's saved in history and server logs.
HTML Form Validation in Real Projects
Validation in practice
Registration and checkout forms on most sites combine HTML attributes for instant feedback with JavaScript for custom messages and server checks for security. Password managers rely on correct autocomplete values, and payment providers use patterns and lengths to catch typos in card details before contacting the bank.
HTML Form Validation Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Make the field mandatory.
<input name="name" >
required stops the form submitting while the field is empty.Which attribute sets the minimum number of characters?
min is for numbers and dates.Which method should a login form use?
What does pattern="[0-9]{5}" require?
{5} repeats the digit class exactly five times.Add validation so the form can't be sent empty: email is required and must be an email address, and the password needs at least 8 characters.
<form>
<label for="e">Email</label>
<input id="e" name="email" type="text">
<label for="p">Password</label>
<input id="p" name="password" type="password">
<button type="submit">Sign in</button>
</form>- Email is required with type email
- Password is required
- Password minlength is 8
HTML Form Validation Quiz
5 questions to check what you learned.
What happens when you submit a form with an empty required field?
- It's sent anyway
- The browser blocks it and shows a message
- The page reloads
- The field is filled automatically
Is HTML validation enough to protect your server?
- Yes
- Only with pattern
- Only for passwords
- No, the server must validate too
What does autocomplete="new-password" help with?
- Telling password managers to suggest a new strong password
- Blocking autofill
- Validating the password
- Hiding the password
What's the difference between :invalid and :user-invalid?
- They're identical
- :invalid is only for numbers
- :user-invalid only applies after the user has interacted with the field
- :user-invalid is a JavaScript method
What does novalidate on a form do?
- Removes all fields
- Validates on the server
- Turns off the browser's built-in validation, usually so JavaScript can handle it
- Hides error messages forever
HTML Form Validation Challenge
A booking form
Build a form with:
- A required
type="email"field withautocomplete="email" - A
type="number"field for guests withmin="1"andmax="8" - A text field with
pattern="[A-Z]{3}[0-9]{3}"and atitleexplaining the format method="post"on the form
- Required email with autocomplete
- Guests between 1 and 8
- Pattern field with a title
- Form uses POST
method="post" on the <form> tag.