Most form-validation tutorials reach for a JavaScript library in the first paragraph. For a normal business form that's backwards: the browser validates required fields, email formats, lengths and patterns natively, in every language your visitors speak, with zero code to maintain. Start there; add JavaScript only for what HTML can't say.
Put the rules in the markup and the browser enforces them on submit — it blocks the send, focuses the first bad field, and explains the problem in the visitor's own language:
<label for="email">Email</label>
<input id="email" name="email" type="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" required
minlength="10" maxlength="2000"></textarea>
That's a complete validation setup for a contact form. No library, nothing to update, and it works with JavaScript disabled.
required — the field must be filled. The single
highest-value attribute; use it exactly on the fields you can't
reply without.type="email", type="url",
type="number" — format checks plus the right mobile
keyboard. (type="tel" gives the keyboard without format
checking — phone formats are too varied to validate;
more on phone fields.)minlength / maxlength — bounds for
text. A minlength of 10 on a message field politely
filters "hi".min / max / step — bounds
for numbers and dates: min="1" keeps a guest count
positive.pattern — a regular expression, for genuinely
structured values like a voucher code. The sharpest knife here and
the easiest to cut yourself with — see below.Two more that aren't validation but belong in the same
pass: autocomplete (e.g. autocomplete="name",
"email", "tel") lets the browser fill the
form from what it already knows — the fastest form is one nobody
types. And inputmode="numeric" brings up a number pad for
digit-only fields that aren't really numbers, like a postcode.
Every rule you add rejects some real person. Names
don't match letter-only patterns (O'Brien, José, 李). Postcodes come
in more formats than any regex you'll write. Phone numbers with
country codes, spaces and dashes are all valid. The test for any
pattern: can you name an honest value it would reject? If
yes, loosen it — a business form's job is receiving messages, not
grading input. Validate strictly only what's truly structural, and
let humans be humans everywhere else.
JavaScript is for presentation: showing errors inline as the visitor types, styling messages to match your brand, submitting without a page reload. Fine — added on top of the HTML rules, they keep working without it.
What client-side validation never does is protect your endpoint. Bots don't read your attributes; they POST straight to the address. Whatever receives your form must enforce its own limits — hform's endpoint caps field counts and sizes, rate-limits, and filters spam server-side regardless of what the HTML said. If you run your own endpoint, do the same.
For the visitor’s experience, usually yes. For safety, no — anything can POST directly to your endpoint, skipping your HTML entirely. The receiving end must apply its own limits; browser validation is comfort, not defense.
The browser’s built-in messages come in the visitor’s language for free, which is hard to beat. Truly custom text needs a few lines of JavaScript (setCustomValidity), and it’s presentation only — keep the HTML rules as the source of truth.
Because real-world values are messier than regexes assume — names with apostrophes and accents, postcodes with spaces, phone numbers with country codes. Reserve pattern for genuinely structured values, and when in doubt, drop the rule.
The hform builder writes this kind of HTML for you — real labels, the right input types, a honeypot, validation that respects your visitors. Build a form in two minutes; free plan included, plain pricing beyond it.
More form craft: Phone fields · File uploads · Form length — or see all guides.