<div class="password-group">
<label for="pwd-input">Create Password</label>
<div class="input-wrapper">
<input type="password" id="pwd-input" placeholder="Enter a strong password">
<div class="strength-ring">
<svg viewBox="0 0 36 36" width="24" height="24">
<path class="ring-bg" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="#e5e7eb" stroke-width="4" />
<path class="ring-progress" id="ring-progress" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="#ef4444" stroke-width="4" stroke-dasharray="100, 100" stroke-dashoffset="100" />
</svg>
</div>
</div>
<p class="hint">Use at least 8 characters, numbers, and symbols.</p>
</div>*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
background: #f9fafb;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
.password-group {
background: #ffffff;
padding: 30px;
border-radius: 16px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
border: 1px solid #f3f4f6;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: #374151;
}
.input-wrapper {
position: relative;
display: flex;
align-items: center;
}
#pwd-input {
width: 100%;
padding: 12px 48px 12px 16px;
border: 1px solid #d1d5db;
border-radius: 8px;
outline: none;
transition: border-color 0.2s;
font-size: 1rem;
color: #111827;
}
#pwd-input:focus {
border-color: #3b82f6;
}
.strength-ring {
position: absolute;
right: 12px;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
}
.ring-progress {
transition: stroke-dashoffset 0.4s ease, stroke 0.4s ease;
}
.hint {
font-size: 0.875rem;
color: #6b7280;
margin-top: 12px;
margin-bottom: 0;
}const input = document.getElementById("pwd-input");
const ring = document.getElementById("ring-progress");
input.addEventListener("input", () => {
const val = input.value;
let score = 0;
// 1. Point for length
if (val.length > 7) {
score++;
}
let hasUpper = false;
let hasNumber = false;
let hasSpecial = false;
// 2. Loop through and look at every single character using charAt()
for (let i = 0; i < val.length; i++) {
const char = val.charAt(i);
if (char >= 'A' && char <= 'Z') {
hasUpper = true;
} else if (char >= '0' && char <= '9') {
hasNumber = true;
} else if (char >= 'a' && char <= 'z') {
// It is a lowercase letter, so we just continue
} else {
// If it is not uppercase, not a number, and not lowercase, it must be a special character
hasSpecial = true;
}
}
// 3. Add points based on what we found
if (hasUpper) score++;
if (hasNumber) score++;
if (hasSpecial) score++;
// 4. Update the visual ring
let offset = 100;
let color = "#ef4444";
if (score === 1) {
offset = 75;
color = "#ef4444";
} else if (score === 2) {
offset = 50;
color = "#f59e0b";
} else if (score === 3) {
offset = 25;
color = "#3b82f6";
} else if (score >= 4) {
offset = 0;
color = "#10b981"; // Green!
}
// Reset if input is empty
if (val.length === 0) {
offset = 100;
}
ring.style.strokeDashoffset = offset;
ring.style.stroke = color;
});Nothing to show yetType HTML, CSS or JavaScript and your page appears here.
Click any element to find its code Esc
Check this code before you run it
It came from a shared link. It runs with fewer permissions, so it cannot open pop-ups, submit forms or start downloads.
0.00s / 0.00s
Nothing has animated yet. Hover, click or type in the preview and each CSS animation, transition or
element.animate() call shows up here as it plays.