Form Validation That Does Not Annoy People
06 Nov 2026Validate too early and you punish people for typing. Validate too late and they hit submit, get a wall of red, and leave. The fix isn’t a smarter library. It’s picking the right moment and the right words for each field.
The three moments
There are only three times you can validate a field, and each one has a job.
- On blur — the field loses focus. Use this for anything that has a clear right/wrong shape: email format, required fields, password rules.
- On input — every keystroke. Use this only to relax an error once it’s fixed, or for things people watch live, like a password strength meter or a username availability check.
- On submit — the whole form. This is your last line of defense, not your first. If submit is the first time someone sees an error, you already validated wrong.
Never validate a required field on input while someone is still typing their first character. An empty field is expected to be empty. Wait for blur.
What to say
“Invalid input” tells a person nothing. Say what’s wrong and how to fix it.
| Bad | Better |
|---|---|
| Invalid email | Enter an email like name@example.com |
| Password invalid | Password needs 8+ characters and one number |
| Required field | Enter your phone number so we can text the code |
Put the message near the field, not in a toast at the top of the page. A toast disappears. A person scrolling a long form won’t scroll back up to reread it.
Where the message goes
Put it directly under the input, not above it. Above the input, the message gets pushed out of view when the keyboard opens on mobile. Below it, it stays next to the thing it’s about.
Reserve the space for the message before it’s needed. If you don’t, the error appearing pushes every field below it down, and people lose their place.
.field {
display: grid;
gap: 4px;
}
.field-error {
min-height: 1.2em; /* reserved even when empty */
color: var(--error);
font-size: 0.875rem;
}
Don’t block on the client alone
Client-side validation is a UX nicety, not a security boundary. Validate again on the server and return field-level errors in the response, not just a 400 with no detail.
// server response shape that a form can actually use
{
"errors": {
"email": "This email is already registered",
"phone": "Enter a valid US phone number"
}
}
If your client validation says a field is fine and the server disagrees, the server error has to land back on that same field, with the same visual treatment. Two different error systems is worse than one plain one.
Disabled submit buttons
Don’t disable the submit button until the form is valid. People click a disabled button, nothing happens, and they assume the page is broken. Let them submit, then show every error at once, focused on the first one.
If you do want to guide people before they submit, use a live “3 of 5 requirements met” style hint for something like a password field — that’s feedback, not a lock.
The one gotcha
Autofill breaks blur-based validation. Browsers fill multiple fields at once without firing blur on each one individually in some cases. Test your validation with actual browser autofill, not just manual typing, or you’ll ship a form that looks broken for the most common real-world input path.
The takeaway: validate on blur, write the message like you’re helping a coworker, put it under the field, and never let the client be the only judge.