Forms that behave before any JavaScript
Required, type, pattern, min, autocomplete, inputmode. Six attributes that replace a validation library and a week of your life.
A form built from the right attributes validates before a single line of your code runs, in every browser, including on the slow phone where your bundle has not finished downloading. This is not a fallback, it is the primary mechanism, and the JavaScript is the enhancement.
Work through the instrument below first. Toggle each attribute on and off and watch three things change: the field’s validity state, the browser’s own error message, and, for inputmode and autocomplete, which keyboard a phone user gets. That last one is invisible on a laptop and enormous on a phone: inputmode="numeric" on a postcode field is the difference between a number pad and hunting through a QWERTY keyboard.
What the attributes already do
JavaScript budget: 0 linesAn empty field blocks submission and reports valueMissing before anything is sent.
typeMismatch on anything that is not an address, plus an email keyboard on a phone and the browser's saved addresses.
patternMismatch as the user types, with no listener attached.
tooShort, and a browser message that names the count the user is missing.
rangeUnderflow and rangeOverflow, plus stepper buttons that stop at the bounds.
The browser and the password manager know what this field is, and fill it in one tap from saved data.
A phone keypad instead of a full keyboard on every touch device.
validationMessage: empty
validationMessage: empty
validationMessage: empty
validationMessage: empty
The @ and the full stop move onto the main row. No space bar hunt.
Focus a different field to see which keyboard it opens. None of this is visible on a desktop, and most of your users are not on one.
- Everything is on. The form validates, names its own errors in the user’s language, opens the right keyboard and offers autofill, with no script.
Zero lines. Required fields, address checking, a pattern, a range, autofill and the right keyboard: all of it declared in the markup, all of it working before a single script has loaded, and all of it still working if the script never arrives.
The messages above are your browser’s, in your browser’s language: the wording differs between Chrome, Firefox and Safari, which is why you never hard-code a comparison against them. Native validation is the floor, not the ceiling: for anything the constraint attributes cannot express, setCustomValidity keeps your rule inside the same machinery.
Then build one yourself. Make a sign-up form with: a name field that is required and has autocomplete="name"; an email field with type="email" and autocomplete="email"; a password with minlength and autocomplete="new-password"; a postcode with inputmode set appropriately for your country and a pattern that matches it; and a date of birth with type="date" and a max that makes someone born tomorrow impossible.
Submit it with everything empty. Read the browser’s own error messages. They are translated into the user’s language, positioned by the browser, and announced by screen readers, and you wrote none of it.
Now add exactly as much JavaScript as improves it and no more: use setCustomValidity to replace one message with a better one, and :user-invalid in CSS to style fields red only after the user has actually interacted with them rather than on page load. That second one is the detail that separates a form that feels helpful from one that feels accusatory.
The autocomplete attribute deserves one more paragraph because it is the most under-used attribute in HTML. With the right token, a browser fills a whole address from a saved profile, a password manager offers the correct credentials, and a phone offers the one-time code from a text message. Without it, the user types everything. The tokens are a fixed published list, look up the right one rather than guessing, because autocomplete="email" works and autocomplete="userEmail" silently does nothing.
Build this in your own editor
This one runs on your machine rather than in the browser workbench. Work to the outcomes below, then come back and mark it complete.
Worth reading
- MDN: Client-side form validation ↗, Every attribute, plus the constraint validation API when you need to go further.
- web.dev: Help users enter the right data in forms ↗, The same ground from the usability side, with the timing of error messages covered properly.
You should now be able to
- Build a form that validates correctly with zero JavaScript
- Choose the right input type and inputmode for a field
- Explain what autocomplete does for a user on a phone
- Read the constraint validation API and use it for custom messages
Loading…