Bootstrap Password Requirements Checklist — Free HTML CSS JS Snippet
Bootstrap Password Requirements Checklist · Forms · Plain HTML, CSS & JS · Live preview
Copy & paste
Source Code
<div class="container py-5 d-flex justify-content-center">
<div class="card bspwreq-card">
<div class="card-body p-4">
<h5 class="fw-bold mb-3">Create a password</h5>
<input type="password" class="form-control mb-3" id="bspwreqInput" placeholder="New password" autocomplete="new-password">
<ul class="list-unstyled mb-3" id="bspwreqList">
<li class="bspwreq-item" data-rule="length"><span class="bspwreq-icon">●</span> At least 8 characters</li>
<li class="bspwreq-item" data-rule="upper"><span class="bspwreq-icon">●</span> One uppercase letter</li>
<li class="bspwreq-item" data-rule="lower"><span class="bspwreq-icon">●</span> One lowercase letter</li>
<li class="bspwreq-item" data-rule="number"><span class="bspwreq-icon">●</span> One number</li>
<li class="bspwreq-item" data-rule="symbol"><span class="bspwreq-icon">●</span> One special character</li>
</ul>
<p class="small text-muted mb-3" id="bspwreqSummary" aria-live="polite">0 of 5 requirements met</p>
<button type="button" class="btn btn-dark w-100 fw-bold" id="bspwreqSubmit" disabled>Create account</button>
</div>
</div>
</div>.bspwreq-card { width: 380px; max-width: 100%; border: 1px solid #eceef1; border-radius: 14px; }
.bspwreq-item { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #6b7280; padding: 3px 0; transition: color .12s; }
.bspwreq-icon { font-size: 8px; color: #d1d5db; transition: color .12s; }
.bspwreq-item-met { color: #198754; }
.bspwreq-item-met .bspwreq-icon { color: #198754; }
.bspwreq-item-met .bspwreq-icon::before { content: "\2713"; font-size: 12px; }const input = document.getElementById('bspwreqInput');
const items = Array.from(document.querySelectorAll('.bspwreq-item'));
const summary = document.getElementById('bspwreqSummary');
const submitBtn = document.getElementById('bspwreqSubmit');
const RULES = {
length: v => v.length >= 8,
upper: v => /[A-Z]/.test(v),
lower: v => /[a-z]/.test(v),
number: v => /[0-9]/.test(v),
symbol: v => /[^A-Za-z0-9]/.test(v),
};
function check() {
const value = input.value;
let metCount = 0;
items.forEach(item => {
const rule = item.dataset.rule;
const met = RULES[rule](value);
item.classList.toggle('bspwreq-item-met', met);
if (met) metCount++;
});
summary.textContent = metCount + ' of ' + items.length + ' requirements met';
submitBtn.disabled = metCount < items.length;
}
input.addEventListener('input', check);
check();Extend with AI
Take This Snippet Further With AI
The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.
What's included
Features
About this UI Snippet
Bootstrap Password Requirements Checklist — HTML, CSS & JavaScript

A strength meter tells you a password is "Strong"; a checklist tells you exactly *which* requirement still isn't met, which is the more useful answer while someone is actively typing. This snippet keeps that mapping explicit with a RULES object where each key is a rule name and each value is a small function that tests the current password — length, upper, lower, number, and symbol are each independently testable, and check() runs every one of them fresh on every keystroke rather than trying to incrementally patch a previous result.
Each <li> carries a data-rule attribute matching one of those keys, so check() never has to hardcode "the third item is the number rule" — it reads the rule name directly off the element it's updating. That's what makes reordering the checklist, or adding a sixth requirement, a one-line change to RULES plus one new <li>, with zero changes to the loop that drives them.
The submit button's disabled state is derived the same way the strikethrough logic elsewhere in this collection is: recomputed from metCount < items.length on every check, rather than toggled by a separate piece of code that could drift out of sync with what the checklist is actually showing. A password that visually satisfies all five items and a submit button that's actually enabled are, by construction, always describing the same fact.
Step by step
How to Use
- 1Load the snippetAll five requirements show as unmet gray dots, and "Create account" is disabled.
- 2Type a lowercase word like "password"The "8 characters" and "lowercase" items turn green; the rest stay gray.
- 3Add an uppercase letter and a numberTwo more items tick off individually as soon as each condition is met.
- 4Add a symbol like ! or #The final requirement turns green and the summary reads "5 of 5 requirements met".
- 5Watch the submit buttonIt enables itself the instant all five are satisfied — no separate validation step required.
- 6Delete a characterAny requirement that no longer holds immediately reverts, and the button disables again if needed.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
A strength meter (see bootstrap-signup-password-strength) collapses everything into one score or label. This checklist keeps every requirement visible and separately answered, which is more actionable while someone is still typing and hasn't met every rule yet.
Yes — add a new key and test function to the RULES object, and add a matching <li data-rule="..."> to the list. The check() function loops over whatever items exist in the DOM, so nothing else needs to change.
The aria-live="polite" summary announces the running count ("3 of 5 requirements met") as it changes, so a screen reader user gets a spoken progress update even without seeing each item individually tick.
Yes. Keep the RULES object as-is, store the password in component state, and derive each item's met boolean and the overall submit-disabled flag directly in the render function instead of toggling classList by hand.
Yes, always — client-side checks like this one are for immediate feedback and a better experience, not security. The same five rules should be re-checked server-side before an account is actually created.