Form validation
Validation is checking that form data is filled in correctly: an email looks like an email, required fields are not empty, an age is a sensible number. The browser can do this on its own based on field attributes: if something is wrong, it does not submit the form and shows a message next to the field.
A required field
The required attribute forbids submitting the form with an empty field:
<form>
<input name="name" required>
<button>Send</button>
</form>Press Send without typing anything — the browser shows a hint like "Please fill in this field". The text and look of the hint depend on the browser.
Text length
minlength and maxlength limit the number of characters. maxlength will not even let you type extra characters, and minlength is checked on submit:
<form>
<label>Username <input name="login" minlength="3" maxlength="12" required></label>
<button>Create</button>
</form>Numbers and dates
For number, range and date fields the limits are set by min and max, and step sets the allowed step:
<form>
<p><label>Guests <input type="number" name="guests" min="1" max="8" required></label></p>
<p><label>Date <input type="date" name="day" min="2026-01-01" required></label></p>
<button>Book</button>
</form>Enter 20 guests — the browser says the value must be 8 or less.
Field type and pattern
email and url fields check the format themselves. For your own rules there is the pattern attribute — a regular expression, a template that the whole text must match:
<form>
<p><label>Email <input type="email" name="email" required></label></p>
<p><label>ZIP code <input name="zip" pattern="[0-9]{5}" title="Five digits"></label></p>
<button>Send</button>
</form>The pattern [0-9]{5} means "exactly five digits". The browser adds the text from title to the error message.
Styling errors
The :user-invalid pseudo-class in CSS selects a field with an error, but only after the user has interacted with it. The similar :invalid matches right away, so an empty form turns red before anyone types:
<style>
input:user-invalid { border: 2px solid crimson; }
input:user-valid { border: 2px solid seagreen; }
</style>
<form>
<label>Email <input type="email" name="email" required></label>
<button>Send</button>
</form>Type something without @ and click outside the field — the border turns red. Pseudo-classes are covered in detail in the CSS chapter.
Turning validation off
The novalidate attribute on a form switches built-in validation off. It is used when validation and error messages are done in JavaScript in your own style:
<form novalidate>
<input type="email" name="email" required>
<button>Send without checks</button>
</form>Common mistake
Browser validation is only a convenience for honest users. It is easy to bypass: remove the attribute in the developer tools or send a request without a browser at all. So the server always checks the data again, and browser validation merely saves people time fixing typos.