HTML + CSS + JavaScript โ real-time validation, password strength, regex patterns, and professional UX patterns.
Zero JavaScript needed โ browser does the work
<input required>
<input type="email">
<input type="number" min="18" max="99">
<input pattern="[A-Z]{3}" title="3 uppercase letters">
a@b passes), limited styling.
input:invalid {
border: 2px solid red;
background: #fff5f5;
}
input:valid {
border: 2px solid green;
background: #f0fdf4;
}
input:required {
border-left: 4px solid #f97316;
}
๐ก Empty required fields are :invalid until user types something.
Why? Real-time messages, complex rules, better UX.
function validateEmail() {
const email = input.value.trim();
const regex = /^[^\s@]+@([^\s@]+\.)+[^\s@]+$/;
if (!regex.test(email)) {
showError("Invalid email");
return false;
}
clearError();
return true;
}
input.addEventListener('input', validateEmail);
form.addEventListener('submit', (e) => {
if (!validateEmail()) {
e.preventDefault(); // STOP submission
}
});
input (real-time) + on submit (final check) + preventDefault()
Password strength meter logic:
const hasNumber = /\d/; const hasLetter = /[A-Za-z]/; const hasSpecial = /[!@#$%^&*]/; let score = 0; if (pwd.length >= 8) score++; if (hasNumber.test(pwd) && hasLetter.test(pwd)) score++; if (hasSpecial.test(pwd)) score++; // score 1 = weak, 2 = medium, 3 = strong
Useful regex patterns:
| Validation | Regex |
|---|---|
| Username (3-15, alnum + _) | /^[A-Za-z0-9_]{3,15}$/ |
/^[^\s@]+@([^\s@]+\.)+[^\s@]+$/ | |
| Phone (10 digits) | /^\d{10}$/ |
| ZIP (5 digits) | /^\d{5}$/ |
| URL | /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/i |
| What | Code |
|---|---|
| Required field | required attribute |
| Email type | type="email" |
| Number range | min="1" max="100" |
| Custom pattern | pattern="[A-Z]{3}" |
| Disable browser validation | novalidate on form |
| Stop form submission | e.preventDefault() |
| Live validation event | input event |
| Trim whitespace | .trim() |