Form validation
A form should not send nonsense. HTML lets you write the rules right on the inputs: required, type="email", min="13". The browser keeps a validity record of true/false flags for every field, updates it as you type, and refuses to send the form until every field is valid. Follow one sign-up form through three presses of Join, then see why the server must check everything again.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01The age field is <input name="age" type="number" min="13"> and it is left empty. What happens when the form is submitted?
Only required makes an empty field invalid. min is checked only when there is a value, so an empty, optional age is valid.
02Someone types kim into <input type="email" required>. Which flag is true?
The field is not empty, so valueMissing is false. But kim does not have the shape of an email address, so typeMismatch is true, and valid is false.
03Both fields are invalid and you press Join. What do Chrome and Firefox do?
Nothing is sent while any field is invalid. The browser reports the problem on the first broken field, in the order the fields appear in the HTML.
04Why must the server check the values again?
Client-side validation helps honest people fix mistakes quickly, but it is easy to bypass. Only the server's own checks can be trusted.
05The valid form is sent with the default method. Where do the values go?
A form's method is GET unless you say otherwise, so each name=value pair is added to the action URL after a ?, joined by &. The @ is written %40.
Glossary
- Validation
- Checking that input follows the rules before it is used or sent.
- Constraint
- A rule on a form field, written as an attribute such as required, type="email" or min="13".
- required
- An attribute that makes an empty field invalid (valueMissing).
- Validity record
- The field's ValidityState: true/false flags, one per kind of problem, plus valid, which is true only when no problem flag is.
- typeMismatch
- The flag that is true when a non-empty value does not have the shape its type asks for, such as an email address without @.
- rangeUnderflow
- The flag that is true when a number is smaller than the field's min.
- Submit
- Sending the form's data to the address in its action attribute, here when the Join button is pressed.
- Server-side validation
- The server checking every value again, because the browser's checks can be skipped.
Notes and sources
- The validity record changes the moment the value changes, but the browser only shows a message when the form is submitted (or when JavaScript calls reportValidity()). CSS can style broken fields as you type with the :invalid pseudo-class, or only after the person has interacted with them with :user-invalid.
- The words in the message bubbles are Chrome's. The HTML standard says the browser must report the problem, not which words to use, so Firefox and Safari word them differently.
- The standard's email rule is loose on purpose: it checks the shape name@domain only, so even a@b passes. It cannot tell whether a mailbox exists.
- Adding novalidate to the form (or formnovalidate to a button) switches the checks off when the form is submitted. That is one more reason the server must check again.
- The figure stacks the two fields to keep them large. With no CSS, labels, fields and the button are inline, so the browser places them side by side and wraps them to the window's width.
- ValidityState has 11 properties: ten kinds of problem (such as tooShort, patternMismatch and rangeOverflow) plus valid. The figure shows the ones these rules can set.
- MDN: Client-side form validation
- MDN: ValidityState
- MDN: Constraint validation
- MDN: <form> (action, method, novalidate)
- MDN: <input type="email">
- MDN: <button> (type defaults to submit)
- MDN: :invalid
- HTML Living Standard: Constraints
- HTML Living Standard: Form submission algorithm
- HTML Living Standard: Email state (valid email address)
- HTML Living Standard: The min and max attributes
- URL Standard: application/x-www-form-urlencoded
Quiz Unlocks after the last step.