PWD001

Password Strength Meter

Modern password validation with visual strength indicator

JavaScript
Font Awesome Included: This snippet uses Font Awesome icons. The required stylesheet is automatically included at the top of the code block. If you are going to use this snippet in your project, add the stylesheet to your <head>.

Live Preview

Enter a password
At least 8 characters
At least 1 uppercase letter
At least 1 lowercase letter
At least 1 number
At least 1 special character

Code

HTML
<!-- 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>
CSS
.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;
  }
}
JavaScript
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];
  }
});