<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 60px 0;
}
.form-container {
max-width: 600px;
margin: 0 auto;
background: white;
border-radius: 20px;
padding: 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
.form-header {
text-align: center;
margin-bottom: 35px;
}
.form-header h2 {
font-size: 2rem;
font-weight: 700;
color: #2c3e50;
margin-bottom: 10px;
}
.form-header p {
color: #7f8c8d;
}
.form-label {
font-weight: 600;
color: #2c3e50;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 5px;
}
.required-star {
color: #e74c3c;
}
.form-control, .form-select {
border: 2px solid #e0e0e0;
border-radius: 10px;
padding: 12px 15px;
transition: all 0.3s ease;
}
.form-control:focus, .form-select:focus {
border-color: #667eea;
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.15);
}
/* Valid State */
.form-control.is-valid, .form-select.is-valid {
border-color: #43e97b;
background-image: none;
}
.form-control.is-valid:focus, .form-select.is-valid:focus {
border-color: #43e97b;
box-shadow: 0 0 0 0.2rem rgba(67, 233, 123, 0.15);
}
/* Invalid State */
.form-control.is-invalid, .form-select.is-invalid {
border-color: #e74c3c;
background-image: none;
}
.form-control.is-invalid:focus, .form-select.is-invalid:focus {
border-color: #e74c3c;
box-shadow: 0 0 0 0.2rem rgba(231, 76, 60, 0.15);
}
/* Feedback Messages */
.valid-feedback, .invalid-feedback {
display: none;
font-size: 0.875rem;
margin-top: 8px;
padding: 8px 12px;
border-radius: 8px;
font-weight: 500;
}
.valid-feedback {
background: #e8f8f0;
color: #27ae60;
border-left: 3px solid #43e97b;
}
.invalid-feedback {
background: #fdeaea;
color: #c0392b;
border-left: 3px solid #e74c3c;
}
.form-control.is-valid ~ .valid-feedback,
.form-select.is-valid ~ .valid-feedback {
display: block;
animation: slideDown 0.3s ease;
}
.form-control.is-invalid ~ .invalid-feedback,
.form-select.is-invalid ~ .invalid-feedback {
display: block;
animation: slideDown 0.3s ease;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Password Strength Meter */
.password-strength {
height: 4px;
background: #e0e0e0;
border-radius: 10px;
margin-top: 10px;
overflow: hidden;
}
.password-strength-bar {
height: 100%;
width: 0%;
transition: all 0.3s ease;
border-radius: 10px;
}
.password-strength-bar.weak {
width: 33%;
background: #e74c3c;
}
.password-strength-bar.medium {
width: 66%;
background: #f39c12;
}
.password-strength-bar.strong {
width: 100%;
background: #43e97b;
}
.password-strength-text {
font-size: 0.8rem;
margin-top: 5px;
font-weight: 600;
}
.password-strength-text.weak { color: #e74c3c; }
.password-strength-text.medium { color: #f39c12; }
.password-strength-text.strong { color: #43e97b; }
/* Character Counter */
.char-counter {
font-size: 0.8rem;
color: #7f8c8d;
text-align: right;
margin-top: 5px;
}
.char-counter.warning {
color: #f39c12;
font-weight: 600;
}
.char-counter.error {
color: #e74c3c;
font-weight: 600;
}
/* Validation Icons */
.input-icon {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
font-size: 1.2rem;
opacity: 0;
transition: opacity 0.3s ease;
}
.input-wrapper {
position: relative;
}
.form-control.is-valid ~ .input-icon.valid,
.form-control.is-invalid ~ .input-icon.invalid {
opacity: 1;
}
.input-icon.valid { color: #43e97b; }
.input-icon.invalid { color: #e74c3c; }
/* Submit Button */
.btn-submit {
width: 100%;
padding: 14px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
color: white;
font-weight: 600;
border-radius: 50px;
transition: all 0.3s ease;
margin-top: 20px;
}
.btn-submit:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4);
}
.btn-submit:disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* Success Alert */
.success-alert {
display: none;
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
color: white;
padding: 20px;
border-radius: 15px;
text-align: center;
margin-top: 20px;
animation: slideDown 0.5s ease;
}
.success-alert.show {
display: block;
}
.success-alert h4 {
margin-bottom: 5px;
font-weight: 700;
}
</style>
<div class="container">
<div class="form-container">
<div class="form-header">
<h2>Sign Up Form</h2>
<p>Fill out the form below with live validation</p>
</div>
<form id="validationForm" novalidate>
<!-- Full Name -->
<div class="mb-4">
<label class="form-label">
Full Name <span class="required-star">*</span>
</label>
<div class="input-wrapper">
<input type="text" class="form-control" id="fullName" required minlength="3">
<span class="input-icon valid">✓</span>
<span class="input-icon invalid">✗</span>
</div>
<div class="valid-feedback">✓ Looks good!</div>
<div class="invalid-feedback">Please enter your full name (at least 3 characters).</div>
</div>
<!-- Email -->
<div class="mb-4">
<label class="form-label">
Email Address <span class="required-star">*</span>
</label>
<div class="input-wrapper">
<input type="email" class="form-control" id="email" required>
<span class="input-icon valid">✓</span>
<span class="input-icon invalid">✗</span>
</div>
<div class="valid-feedback">✓ Valid email address!</div>
<div class="invalid-feedback">Please enter a valid email address.</div>
</div>
<!-- Password -->
<div class="mb-4">
<label class="form-label">
Password <span class="required-star">*</span>
</label>
<div class="input-wrapper">
<input type="password" class="form-control" id="password" required minlength="8">
<span class="input-icon valid">✓</span>
<span class="input-icon invalid">✗</span>
</div>
<div class="password-strength">
<div class="password-strength-bar" id="strengthBar"></div>
</div>
<div class="password-strength-text" id="strengthText"></div>
<div class="valid-feedback">✓ Strong password!</div>
<div class="invalid-feedback">Password must be at least 8 characters long.</div>
</div>
<!-- Confirm Password -->
<div class="mb-4">
<label class="form-label">
Confirm Password <span class="required-star">*</span>
</label>
<div class="input-wrapper">
<input type="password" class="form-control" id="confirmPassword" required>
<span class="input-icon valid">✓</span>
<span class="input-icon invalid">✗</span>
</div>
<div class="valid-feedback">✓ Passwords match!</div>
<div class="invalid-feedback">Passwords do not match.</div>
</div>
<!-- Phone Number -->
<div class="mb-4">
<label class="form-label">
Phone Number <span class="required-star">*</span>
</label>
<div class="input-wrapper">
<input type="tel" class="form-control" id="phone" required pattern="[0-9+\-\s()]+">
<span class="input-icon valid">✓</span>
<span class="input-icon invalid">✗</span>
</div>
<div class="valid-feedback">✓ Valid phone number!</div>
<div class="invalid-feedback">Please enter a valid phone number.</div>
</div>
<!-- Bio -->
<div class="mb-4">
<label class="form-label">
Bio <span class="text-muted">(Optional)</span>
</label>
<textarea class="form-control" id="bio" rows="3" maxlength="200"></textarea>
<div class="char-counter" id="charCounter">0 / 200 characters</div>
</div>
<!-- Country -->
<div class="mb-4">
<label class="form-label">
Country <span class="required-star">*</span>
</label>
<select class="form-select" id="country" required>
<option value="">Choose your country</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca">Canada</option>
<option value="au">Australia</option>
<option value="pk">Pakistan</option>
<option value="in">India</option>
</select>
<div class="valid-feedback">✓ Country selected!</div>
<div class="invalid-feedback">Please select your country.</div>
</div>
<!-- Terms & Conditions -->
<div class="mb-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="terms" required>
<label class="form-check-label" for="terms">
I agree to the Terms and Conditions <span class="required-star">*</span>
</label>
<div class="invalid-feedback">You must agree before submitting.</div>
</div>
</div>
<!-- Submit Button -->
<button type="submit" class="btn btn-submit" id="submitBtn">Create Account</button>
<!-- Success Alert -->
<div class="success-alert" id="successAlert">
<h4>✓ Account Created Successfully!</h4>
<p>Welcome aboard! Your account has been created.</p>
</div>
</form>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
// Get form elements
const form = document.getElementById('validationForm');
const fullName = document.getElementById('fullName');
const email = document.getElementById('email');
const password = document.getElementById('password');
const confirmPassword = document.getElementById('confirmPassword');
const phone = document.getElementById('phone');
const bio = document.getElementById('bio');
const country = document.getElementById('country');
const terms = document.getElementById('terms');
const charCounter = document.getElementById('charCounter');
const strengthBar = document.getElementById('strengthBar');
const strengthText = document.getElementById('strengthText');
const successAlert = document.getElementById('successAlert');
// Real-time validation for all inputs
function validateInput(input) {
if (input.value.trim() === '') {
input.classList.remove('is-valid', 'is-invalid');
return;
}
if (input.checkValidity()) {
input.classList.remove('is-invalid');
input.classList.add('is-valid');
} else {
input.classList.remove('is-valid');
input.classList.add('is-invalid');
}
}
// Validate full name
fullName.addEventListener('input', () => validateInput(fullName));
// Validate email
email.addEventListener('input', () => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (email.value && emailRegex.test(email.value)) {
email.classList.remove('is-invalid');
email.classList.add('is-valid');
} else if (email.value) {
email.classList.remove('is-valid');
email.classList.add('is-invalid');
} else {
email.classList.remove('is-valid', 'is-invalid');
}
});
// Password strength checker
password.addEventListener('input', () => {
const value = password.value;
let strength = 0;
if (value.length >= 8) strength++;
if (value.match(/[a-z]/) && value.match(/[A-Z]/)) strength++;
if (value.match(/[0-9]/)) strength++;
if (value.match(/[^a-zA-Z0-9]/)) strength++;
strengthBar.className = 'password-strength-bar';
strengthText.className = 'password-strength-text';
if (value.length === 0) {
strengthBar.style.width = '0%';
strengthText.textContent = '';
} else if (strength <= 2) {
strengthBar.classList.add('weak');
strengthText.classList.add('weak');
strengthText.textContent = 'Weak password';
} else if (strength === 3) {
strengthBar.classList.add('medium');
strengthText.classList.add('medium');
strengthText.textContent = 'Medium password';
} else {
strengthBar.classList.add('strong');
strengthText.classList.add('strong');
strengthText.textContent = 'Strong password';
}
validateInput(password);
validateConfirmPassword();
});
// Validate confirm password
function validateConfirmPassword() {
if (confirmPassword.value === '') {
confirmPassword.classList.remove('is-valid', 'is-invalid');
return;
}
if (confirmPassword.value === password.value && password.value.length >= 8) {
confirmPassword.classList.remove('is-invalid');
confirmPassword.classList.add('is-valid');
} else {
confirmPassword.classList.remove('is-valid');
confirmPassword.classList.add('is-invalid');
}
}
confirmPassword.addEventListener('input', validateConfirmPassword);
// Validate phone
phone.addEventListener('input', () => validateInput(phone));
// Character counter for bio
bio.addEventListener('input', () => {
const length = bio.value.length;
const max = 200;
charCounter.textContent = `${length} / ${max} characters`;
if (length > max * 0.9) {
charCounter.classList.add('warning');
} else {
charCounter.classList.remove('warning');
}
if (length === max) {
charCounter.classList.add('error');
} else {
charCounter.classList.remove('error');
}
});
// Validate country
country.addEventListener('change', () => validateInput(country));
// Form submission
form.addEventListener('submit', (e) => {
e.preventDefault();
// Validate all fields
const inputs = [fullName, email, password, confirmPassword, phone, country];
let isValid = true;
inputs.forEach(input => {
if (!input.checkValidity()) {
input.classList.add('is-invalid');
isValid = false;
} else {
input.classList.add('is-valid');
}
});
if (!terms.checked) {
terms.classList.add('is-invalid');
isValid = false;
}
if (confirmPassword.value !== password.value) {
confirmPassword.classList.add('is-invalid');
isValid = false;
}
if (isValid) {
// Show success message
successAlert.classList.add('show');
form.reset();
document.querySelectorAll('.is-valid, .is-invalid').forEach(el => {
el.classList.remove('is-valid', 'is-invalid');
});
strengthBar.style.width = '0%';
strengthText.textContent = '';
charCounter.textContent = '0 / 200 characters';
// Hide success message after 5 seconds
setTimeout(() => {
successAlert.classList.remove('show');
}, 5000);
}
});
</script>
Login to leave a comment
Login
No comments yet. Be the first!