HTML Form Validation
Introduction to Form Validation
Form validation is the process of checking user input to ensure it meets specified criteria before submitting the data to the server. HTML5 introduced built-in form validation features that allow you to validate user input directly in the browser without JavaScript.
There are two main types of form validation:
- Client-side validation: Happens in the browser before data is sent to the server
- Server-side validation: Happens on the server after data is submitted
HTML5 Built-in Validation
HTML5 provides several attributes for basic form validation:
Required Fields
The required
attribute specifies that an input field must be filled out before submitting the form:
<input type="text" name="username" required>
Min and Max Values
The min
and max
attributes specify the minimum and maximum values for numeric input types:
<input type="number" name="age" min="18" max="120">
Min and Max Length
The minlength
and maxlength
attributes specify the minimum and maximum number of characters allowed in a text field:
<input type="text" name="username" minlength="3" maxlength="15">
Pattern Matching
The pattern
attribute specifies a regular expression that the input value must match:
<input type="text" name="zipcode" pattern="[0-9]{5}" title="Five digit zip code">
Input Type Validation
Certain HTML5 input types have built-in validation:
Email Validation
The email
input type validates that the input is a properly formatted email address:
<input type="email" name="email">
URL Validation
The url
input type validates that the input is a properly formatted URL:
<input type="url" name="website">
Number Validation
The number
input type validates that the input is a number and provides increment/decrement buttons:
<input type="number" name="quantity" min="1" max="10" step="1">
Validation Feedback
Browsers provide visual feedback for validation errors, but you can also use the CSS :valid
and :invalid
pseudo-classes to style valid and invalid inputs:
input:valid {
border-color: green;
}
input:invalid {
border-color: red;
}
You can also use the :required
, :optional
, :in-range
, and :out-of-range
pseudo-classes for more specific styling.
Custom Validation Messages
The title
attribute can be used to provide a custom validation message:
<input type="text" pattern="[A-Za-z]{3}" title="Three letter country code">
The Constraint Validation API
HTML5 also provides a JavaScript API for form validation, known as the Constraint Validation API. This API gives you more control over the validation process:
// Check if an input is valid
const isValid = document.getElementById('email').validity.valid;
// Get validation message
const message = document.getElementById('email').validationMessage;
// Check specific validity states
const isTooShort = document.getElementById('username').validity.tooShort;
const isPatternMismatch = document.getElementById('zipcode').validity.patternMismatch;
// Set a custom validation message
document.getElementById('password').setCustomValidity('Passwords must match');
// Clear a custom validation message
document.getElementById('password').setCustomValidity('');
The validity
property provides information about the validity of an input, including:
valueMissing
: The element has arequired
attribute but no valuetypeMismatch
: The value is not of the correct type (e.g., email, url)patternMismatch
: The value doesn't match the specified patterntooLong
: The value exceeds themaxlength
attributetooShort
: The value is shorter than theminlength
attributerangeUnderflow
: The value is less than themin
attributerangeOverflow
: The value is greater than themax
attributestepMismatch
: The value doesn't match the specifiedstep
badInput
: The browser can't convert the input to a valid valuecustomError
: The element has a custom validation error messagevalid
: The element meets all validation constraints
Complete Form Validation Example
Here's a complete example of a form with various validation techniques:
<form id="registration-form" novalidate>
<div>
<label for="username">Username (3-15 characters):</label>
<input type="text" id="username" name="username" minlength="3" maxlength="15" required>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="password">Password (min 8 characters):</label>
<input type="password" id="password" name="password" minlength="8" required>
</div>
<div>
<label for="confirm-password">Confirm Password:</label>
<input type="password" id="confirm-password" name="confirm-password" required>
</div>
<div>
<label for="age">Age (18-120):</label>
<input type="number" id="age" name="age" min="18" max="120" required>
</div>
<div>
<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}" required>
</div>
<div>
<label for="website">Website:</label>
<input type="url" id="website" name="website">
</div>
<div>
<label for="zipcode">Zip Code (5 digits):</label>
<input type="text" id="zipcode" name="zipcode" pattern="[0-9]{5}" title="Five digit zip code">
</div>
<div>
<label>
<input type="checkbox" name="terms" required>
I agree to the terms and conditions
</label>
</div>
<button type="submit">Register</button>
</form>
<script>
const form = document.getElementById('registration-form');
const password = document.getElementById('password');
const confirmPassword = document.getElementById('confirm-password');
// Custom validation for password matching
function validatePassword() {
if (password.value !== confirmPassword.value) {
confirmPassword.setCustomValidity('Passwords do not match');
} else {
confirmPassword.setCustomValidity('');
}
}
password.addEventListener('change', validatePassword);
confirmPassword.addEventListener('keyup', validatePassword);
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault();
// Show validation messages
const inputs = form.querySelectorAll('input');
inputs.forEach(input => {
if (!input.validity.valid) {
// You could add custom error handling here
console.log(input.name + ': ' + input.validationMessage);
}
});
}
});
</script>
This example demonstrates:
- Required fields
- Length constraints
- Type validation (email, url, number, tel)
- Pattern validation
- Range validation
- Custom validation (password matching)
- Form submission handling
Best Practices for Form Validation
- Always implement both client-side and server-side validation
- Use the appropriate input types for automatic validation
- Provide clear, helpful error messages
- Validate in real-time when possible (e.g., as the user types or when they leave a field)
- Use the
title
attribute to provide hints about expected input format - Consider accessibility when implementing validation (screen readers should announce validation errors)
- Test validation on different browsers and devices
- Use the
novalidate
attribute on the form if you want to implement custom validation with JavaScript - Don't rely solely on HTML5 validation for complex validation rules
- Consider using a validation library for complex forms