Modern password validation with visual strength indicator
<head>
.<!-- Font Awesome Icons; Make sure to add it in the <head> tag -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<div class="password-strength-container">
<div class="password-input-group">
<input type="password" class="password-input" id="password" placeholder="Enter password">
<button type="button" class="password-toggle" id="toggle-password">
<i class="fas fa-eye"></i>
</button>
</div>
<div class="strength-meter">
<div class="strength-meter-fill" id="strength-fill"></div>
</div>
<div class="strength-text" id="strength-text">Enter a password</div>
<div class="strength-requirements">
<div class="requirement" id="length">
<i class="fas fa-times-circle"></i>
At least 8 characters
</div>
<div class="requirement" id="uppercase">
<i class="fas fa-times-circle"></i>
At least 1 uppercase letter
</div>
<div class="requirement" id="lowercase">
<i class="fas fa-times-circle"></i>
At least 1 lowercase letter
</div>
<div class="requirement" id="number">
<i class="fas fa-times-circle"></i>
At least 1 number
</div>
<div class="requirement" id="special">
<i class="fas fa-times-circle"></i>
At least 1 special character
</div>
</div>
</div>
.password-strength-container {
width: 100%;
max-width: 400px;
display: flex;
flex-direction: column;
gap: 20px;
font-family: 'Arial', sans-serif;
}
.password-input-group {
position: relative;
width: 100%;
}
.password-input {
width: 100%;
padding: 12px 40px 12px 16px;
border: 1px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
background-color: #fff;
color: #333;
transition: border-color 0.3s, box-shadow 0.3s;
}
.password-input:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.15);
}
.password-toggle {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: #777;
cursor: pointer;
font-size: 16px;
transition: color 0.2s;
}
.password-toggle:hover {
color: #3498db;
}
.strength-meter {
width: 100%;
height: 8px;
background-color: #e0e0e0;
border-radius: 4px;
margin-top: 8px;
overflow: hidden;
position: relative;
}
.strength-meter-fill {
height: 100%;
width: 0;
border-radius: 4px;
transition: width 0.5s ease, background-color 0.5s ease;
}
.strength-text {
font-size: 14px;
margin-top: 8px;
font-weight: 500;
transition: color 0.3s;
}
.strength-requirements {
margin-top: 16px;
}
.requirement {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 6px;
font-size: 14px;
color: #777;
}
.requirement i {
font-size: 14px;
width: 16px;
text-align: center;
}
.requirement.valid {
color: #4caf50;
}
.requirement.valid i {
color: #4caf50;
}
/* Strength levels */
.strength-very-weak .strength-meter-fill {
width: 20%;
background-color: #ff4d4d;
}
.strength-weak .strength-meter-fill {
width: 40%;
background-color: #ffa64d;
}
.strength-medium .strength-meter-fill {
width: 60%;
background-color: #ffdb4d;
}
.strength-strong .strength-meter-fill {
width: 80%;
background-color: #9ee34d;
}
.strength-very-strong .strength-meter-fill {
width: 100%;
background-color: #4caf50;
}
.strength-very-weak .strength-text {
color: #ff4d4d;
}
.strength-weak .strength-text {
color: #ffa64d;
}
.strength-medium .strength-text {
color: #ffdb4d;
}
.strength-strong .strength-text {
color: #9ee34d;
}
.strength-very-strong .strength-text {
color: #4caf50;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
.password-input {
background-color: #222;
border-color: #444;
color: #eee;
}
.strength-meter {
background-color: #373737;
}
}
document.addEventListener('DOMContentLoaded', function() {
const passwordInput = document.getElementById('password');
const togglePassword = document.getElementById('toggle-password');
const strengthFill = document.getElementById('strength-fill');
const strengthText = document.getElementById('strength-text');
const lengthReq = document.getElementById('length');
const uppercaseReq = document.getElementById('uppercase');
const lowercaseReq = document.getElementById('lowercase');
const numberReq = document.getElementById('number');
const specialReq = document.getElementById('special');
// Toggle password visibility
togglePassword.addEventListener('click', function() {
const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password';
passwordInput.setAttribute('type', type);
// Toggle eye icon
const icon = togglePassword.querySelector('i');
icon.classList.toggle('fa-eye');
icon.classList.toggle('fa-eye-slash');
});
// Check password strength on input
passwordInput.addEventListener('input', function() {
const password = passwordInput.value;
const container = passwordInput.closest('.password-strength-container');
// Remove all strength classes
container.classList.remove(
'strength-very-weak',
'strength-weak',
'strength-medium',
'strength-strong',
'strength-very-strong'
);
// Check requirements
const hasLength = password.length >= 8;
const hasUppercase = /[A-Z]/.test(password);
const hasLowercase = /[a-z]/.test(password);
const hasNumber = /[0-9]/.test(password);
const hasSpecial = /[^A-Za-z0-9]/.test(password);
// Update requirement status
updateRequirement(lengthReq, hasLength);
updateRequirement(uppercaseReq, hasUppercase);
updateRequirement(lowercaseReq, hasLowercase);
updateRequirement(numberReq, hasNumber);
updateRequirement(specialReq, hasSpecial);
// Calculate strength score (0-5)
let strengthScore = 0;
if (password.length > 0) strengthScore += 1;
if (hasLength) strengthScore += 1;
if (hasUppercase) strengthScore += 1;
if (hasLowercase) strengthScore += 1;
if (hasNumber) strengthScore += 1;
if (hasSpecial) strengthScore += 1;
// Adjust score to max of 5
strengthScore = Math.min(5, Math.floor(strengthScore * 5 / 6));
// Update strength meter and text
updateStrengthMeter(container, strengthScore, strengthText);
});
function updateRequirement(element, isValid) {
const icon = element.querySelector('i');
if (isValid) {
element.classList.add('valid');
icon.classList.remove('fa-times-circle');
icon.classList.add('fa-check-circle');
} else {
element.classList.remove('valid');
icon.classList.remove('fa-check-circle');
icon.classList.add('fa-times-circle');
}
}
function updateStrengthMeter(container, score, textElement) {
const strengthClasses = [
'',
'strength-very-weak',
'strength-weak',
'strength-medium',
'strength-strong',
'strength-very-strong'
];
const strengthTexts = [
'Enter a password',
'Very weak',
'Weak',
'Medium',
'Strong',
'Very strong'
];
// Add appropriate class
if (score > 0) {
container.classList.add(strengthClasses[score]);
}
// Update text
textElement.textContent = strengthTexts[score];
}
});