HTML
Form Validation Basics
Make forms smarter by checking data before it gets submitted to your server
Alex's portfolio needs a contact form that actually works. Right now, visitors can submit empty messages or fake email addresses. That's not helpful for anyone. HTML has built-in validation that stops bad data before it leaves the browser. Think of validation like a bouncer at a club. The bouncer checks IDs before people get inside. Form validation checks data before it gets sent to your server. No empty required fields. No fake emails. No passwords that are too short.The Required Attribute
Therequired attribute is your most basic validation tool. Add it to any input that must be filled out. When someone tries to submit the form with empty required fields, the browser stops them and shows an error message.
Here's how Alex can make the name and email fields required on their contact form:
<!-- Alex's contact form with required validation -->
<form>
<label for="name">Your Name:</label>
<input type="text" id="name" name="name" required>
<label for="email">Email Address:</label>
<input type="email" id="email" name="email" required>
<label for="message">Message:</label>
<textarea id="message" name="message"></textarea>
<button type="submit">Send Message</button>
</form>What just happened?
The form now requires a name and email before submission. Try clicking "Send Message" without filling them out. The browser will focus the first empty required field and show an error message. The message field is optional since it doesn't have required.
Input Type Validation
Remember those input types from the previous lesson? Many of them come with automatic validation. Anemail input checks for valid email format. A url input makes sure the text looks like a website address.
The browser does this checking for free. You don't write any code. Just pick the right input type and the browser handles the rest.
<!-- Different input types with built-in validation -->
<form>
<label for="email">Email (must be valid format):</label>
<input type="email" id="email" name="email" required>
<label for="website">Website (must be valid URL):</label>
<input type="url" id="website" name="website">
<label for="phone">Phone Number:</label>
<input type="tel" id="phone" name="phone">
<button type="submit">Submit</button>
</form>What just happened?
Try typing "hello" in the email field and submitting. The browser knows that's not a valid email format. Try entering "badwebsite" in the URL field. The browser expects URLs to start with http:// or https://. These checks happen automatically based on the input type.
Length Limits
Sometimes you need to control how much text people can enter. Maybe your database can only store 50 characters for a username. Or you want to limit messages to 500 characters to keep them readable. Theminlength and maxlength attributes set character limits. The browser counts characters as someone types and stops them when they hit the limit.
<!-- Alex's signup form with length validation -->
<form>
<label for="username">Username (3-20 characters):</label>
<input type="text" id="username" name="username"
minlength="3" maxlength="20" required>
<label for="bio">Bio (max 200 characters):</label>
<textarea id="bio" name="bio" maxlength="200"></textarea>
<label for="password">Password (min 8 characters):</label>
<input type="password" id="password" name="password"
minlength="8" required>
<button type="submit">Create Account</button>
</form>What just happened?
Try typing in the textarea. When you reach 200 characters, the browser stops accepting more input. Try submitting with a 2-character username or 5-character password. The browser will reject it and show an error message about length requirements.
Number Ranges
Number inputs can have minimum and maximum values usingmin and max attributes. Great for things like age, quantity, or price ranges. The browser won't let people enter numbers outside your specified range.
You can also set a step attribute to control what increments are allowed. Step of 0.01 for currency. Step of 5 for quantities sold in packs of 5.
<!-- Alex's product order form with number validation -->
<form>
<label for="age">Your Age (18-120):</label>
<input type="number" id="age" name="age"
min="18" max="120" required>
<label for="quantity">Quantity (1-10):</label>
<input type="number" id="quantity" name="quantity"
min="1" max="10" value="1">
<label for="price">Budget ($10-$1000):</label>
<input type="number" id="price" name="price"
min="10" max="1000" step="0.01">
<button type="submit">Place Order</button>
</form>What just happened?
Try entering 15 in the age field and submitting. The browser rejects it because the minimum is 18. Try entering 15.5 in the budget field — it works because step="0.01" allows decimal places. The quantity field uses the up/down arrows to increment by 1 (the default step).
Pattern Matching
For more complex validation, you can use thepattern attribute. This uses regular expressions (regex) — a way to describe text patterns. Don't worry about learning regex now, but here are some useful patterns you can copy and paste.
The title attribute shows a custom error message when the pattern doesn't match. Much more helpful than the browser's default message.
<!-- Alex's registration form with pattern validation -->
<form>
<label for="username">Username (letters and numbers only):</label>
<input type="text" id="username" name="username"
pattern="[a-zA-Z0-9]+"
title="Only letters and numbers allowed" required>
<label for="phone">Phone (format: 123-456-7890):</label>
<input type="tel" id="phone" name="phone"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
title="Format: 123-456-7890" required>
<label for="zipcode">ZIP Code (5 digits):</label>
<input type="text" id="zipcode" name="zipcode"
pattern="[0-9]{5}"
title="Must be exactly 5 digits" required>
<button type="submit">Register</button>
</form>What just happened?
Try entering "user@name" in the username field — the @ symbol isn't allowed by the pattern. Try "123456-7890" for the phone — it needs exactly 3 digits, then a dash, then 3 digits, then another dash, then 4 digits. The custom title messages show up when validation fails.
Common Pattern Mistakes
Patterns are case-sensitive. If you want uppercase AND lowercase letters, include both: [a-zA-Z]. Also, patterns must match the entire input, not just part of it. The pattern [0-9]{5} only accepts exactly 5 digits, nothing more or less.
Putting It All Together
Here's Alex's complete contact form using multiple validation techniques. Notice how different validation types work together to create a robust form that catches most user errors before submission.<!-- Alex's complete validated contact form -->
<form>
<h2>Contact Alex</h2>
<label for="fullname">Full Name:</label>
<input type="text" id="fullname" name="fullname"
minlength="2" maxlength="50" required>
<label for="email">Email Address:</label>
<input type="email" id="email" name="email" required>
<label for="budget">Project Budget ($100-$10000):</label>
<input type="number" id="budget" name="budget"
min="100" max="10000" step="100">
<label for="message">Project Description (10-500 characters):</label>
<textarea id="message" name="message"
minlength="10" maxlength="500" required></textarea>
<button type="submit">Send Message</button>
</form>Form validation makes your site feel professional. Users get instant feedback instead of waiting for a server response. And you prevent bad data from reaching your database. Both sides win.
Quiz
Alex wants to make the email field mandatory in their contact form. Which attribute should they add to the input element?
Alex wants to limit a username field to between 8 and 20 characters. Which attributes should they use on a text input?
What happens when Alex adds validation attributes to their form inputs?
Up Next: Buttons and Actions
Different button types and how to make forms actually do something when submitted.