Form Validation
A good receptionist catches a missing signature before you've walked away from the desk. That's validation.
Picture handing in a form at a busy office. A good receptionist glances over it right there: "Oh, you missed the date of birth. And the phone number's one digit short." Thirty seconds, fixed, done.
A bad one takes it without looking, and three days later you get a letter saying your application was rejected for a missing field. Now you have to start over.
Form validation is how you make your site the good receptionist. And the wonderful part? For most everyday checks, HTML does it for you with a single attribute. No programming needed.
required: don't leave this blank
<label for="full-name">Full name</label>
<input type="text" id="full-name" name="full-name" required>That's it. If someone tries to submit with this empty, the browser stops them and points at the field with a message. required is a boolean attribute, just like checked and disabled from Attributes: its presence is the switch.
The input type already checks for you
Remember choosing type="email" back in Forms: The Basics? That did more than change the phone keyboard. The browser now rejects answers that aren't shaped like an email address. "banana" won't get through. Neither will "maria@". Same goes for type="url" and type="number".
That's one more reason to always pick the most specific type.
Length and range
<!-- Between 8 and 64 characters -->
<input type="password" id="password" name="password" minlength="8" maxlength="64" required>
<!-- A whole number from 1 to 10 -->
<input type="number" id="guests" name="guests" min="1" max="10" step="1">
<!-- No dates before January 1, 2026 -->
<input type="date" id="booking-date" name="booking-date" min="2026-01-01">maxlengthstops typing past the limit, andminlengthis checked when the form is submitted.minandmaxlimit numbers and dates.stepsets the allowed increments.step="0.5"allows 1, 1.5, 2, and so on.
(To make the earliest date always today, you'd set min with JavaScript, since plain HTML can't know what day it is.)
pattern: your own rule
Sometimes you need a specific shape, like a product code that's always three letters then four digits: ABC1234.
<label for="product-code">Product code</label>
<input
type="text"
id="product-code"
name="product-code"
pattern="[A-Z]{3}[0-9]{4}"
aria-describedby="product-code-hint"
required>
<p id="product-code-hint">Three capital letters then four numbers, like ABC1234.</p>That odd-looking [A-Z]{3}[0-9]{4} is a regular expression, a tiny language for describing text shapes. Read it as "three of A to Z, then four of 0 to 9." The pattern has to match the whole answer, not just part of it. Don't worry about learning regular expressions right now. They're a whole topic of their own, and you'll meet them properly in Strings and Regular Expressions. For now, just know that pattern exists and roughly how to read a simple one.
Tell people the rules before they break them
Look at that hint paragraph above. Nothing is more frustrating than being told "Invalid format" with no idea what the right format is. It's like a receptionist who just keeps saying "No" without telling you why.
So write the rule where people can see it before they type. Then connect it to the input with aria-describedby, pointing to the hint's id. A screen reader will now read the label, then the hint: "Product code, edit text. Three capital letters then four numbers, like ABC1234." Everyone gets the same heads-up. You'll see more of these aria- connections in Accessibility Basics.
And mark required fields visibly, not just in code. The word "(required)" in the label works great for everyone.
The big warning: the receptionist is not the security guard
Please read this part twice.
Browser validation is a convenience for honest visitors. It is not security. Anyone who knows how can switch it off, edit your HTML in their browser's developer tools, or send data to your server without using your form at all.
The receptionist catches honest mistakes. But the building still needs a security guard at the back door, checking everything that comes in no matter how it arrived. In web terms, that guard is your server, which must validate every answer again, every time. You'll build that guard when you get to the backend tracks. For now, just never believe "the form checks it" means your data is safe.
Skipping validation on purpose
<form novalidate>novalidate turns off the browser's built-in checks for the whole form. Developers sometimes do this when they write their own validation with JavaScript to show custom messages. You'll learn how that works in Forms and Custom Validation. Until then, let the browser do its job.
Try it
The preview is a locked-down sandbox that blocks real form submissions, so a tiny helper script in the JavaScript pane asks the browser to run its checks when you press the button. You don't need to understand the script yet.
HTML
CSS
JavaScript
Preview
Try it yourself
- Press "Book a table" with everything empty. The browser points you at the first problem.
- Type
bananaas the email. Type12guests. Typeabc1234(lowercase) as the voucher. Each one gets caught. - Add
minlength="2"to the name field, then test it with a single letter.
Check your understanding
Up next
Forms are done, and that was a big chapter. Seriously, take a breath. You can now build a real, working conversation with your visitors. Next, we zoom out from single elements to the structure of a whole page, starting with the humble generic boxes in Divs and Spans.
