Forms✨ Premium

Password Strength

Under the password field, a bar fills a third, two thirds or all the way, with a Weak, Medium or Strong verdict recomputed on every key.

JSAnimationSecurity

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Forms has 20 effects, including 2 free. Explore the category →

3 usage examples

Online bank sign-up — the gauge under the new-password field — Password Strength example 1

① Online bank sign-up — the gauge under the new-password field

WhenThe new customer picks a password: the bar goes from Weak to Medium then Strong as a digit and a symbol are added.
WhyThe rule shown right below (10 characters, uppercase, digit, symbol) is checked live: the customer knows they are done without waiting for a refusal on submit.
SettingsLight theme: --pwsm-field:#fff, --pwsm-border:#cfd8e3, --pwsm-track:#e2e8f0, --pwsm-text:#0b1b33, state colours darkened for a white background (--pwsm-weak:#dc2626, --pwsm-medium:#d97706, --pwsm-strong:#059669), 5 px bar, 100% width. Typing driven by the scene.
Awareness workshop — a gauge readable from the back of the room — Password Strength example 2

② Awareness workshop — a gauge readable from the back of the room

WhenThe trainer tries three examples on screen: "soleil", "Soleil24", "Soleil24!Marée". The room watches the bar grow and the verdict change.
WhyEnlarged, the gauge becomes a teaching aid: everyone sees what a digit or a symbol changes, with no jargon.
Settings--pwsm-width:100%, --pwsm-font-size:1.6rem, --pwsm-bar-height:12px, --pwsm-label-size:1.4rem, field set to type="text" so the examples can be read. The tries are set by the scene.
Security settings — a password generated with one click — Password Strength example 3

③ Security settings — a password generated with one click

WhenIn the "Password" row of a settings page, the old password shows as "Weak". A click on Generate fills the field and the bar turns green.
WhyFeedback is instant on an action that is not typing: the gauge confirms the suggestion is solid before saving.
SettingsSmall size in a light theme (--pwsm-font-size:.875rem, --pwsm-focus:#7c3aed), field prefilled through value: the effect rates it on load. The Generate button belongs to the scene; it sets the value then fires input, which the effect listens to.

How it works

On every input event, the password earns one point per criterion met: 6 characters or more, 10 or more, an uppercase letter (A-Z), a digit, a character that is neither a letter nor a digit (accents included). 0 to 2 points: bar at 33% in red and "Weak"; 3 points: 66% in orange and "Medium"; 4 or 5: full green bar and "Strong". Empty field: empty bar and the starting text, "Password strength".

The state lives in a single attribute, data-strength on .pwsm-group (empty, weak, medium, strong); the CSS derives width and colours from it and the bar slides in 0.4 s. No inline style is written on the bar: clearing the field and typing again makes it start over normally.

Labels are read from the HTML (hidden .pwsm-words block), so the same script works in French and English. The score checks no list of known passwords: "Password1!" gets "Strong". It is a hint that guides typing, not a server-side security check.

Accessibility

  • Label and autofill: "Password" in a visually hidden <label>, autocomplete="new-password" so password managers offer to generate one.
  • Verdict announced: the text under the bar is an aria-live="polite" region rewritten only when the verdict changes; the field points to it through aria-describedby.
  • Not colour alone: each level has its own bar length and word; the bar itself is aria-hidden.
  • Reduced motion: under prefers-reduced-motion: reduce, the bar changes length without sliding.
  • Limit: the score does not say which criterion is missing. Keep a visible sentence listing the rules (as in the bank example).

Browser compatibility

2 KB of JavaScript, CSS with variables and attribute selectors. Measured on 08/11/2026 in Chromium, Firefox and WebKit (Playwright): full green bar after clearing the field and typing again, two independent copies, touch at 390 px, reduced motion, no errors. Floor set by NodeList.forEach (Chrome 51, Firefox 50, Safari 10, according to @mdn/browser-compat-data).

Chrome 51+✓ Full (measured)
Firefox 50+✓ Full (measured)
Safari 10+✓ Full (measured in WebKit)
Edge 79+✓ Full (Chromium engine)
iOS Safari 10+✓ Not checked on a real device
Android Chrome 51+✓ Full (Chromium engine)

Without JavaScript the password field works normally; the bar stays empty and the "Password strength" text never changes.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0286-root">
  <div class="pwsm-group" data-strength="empty">
    <label class="pwsm-field">
      <span class="pwsm-sr">Password</span>
      <input class="pwsm-input" type="password" name="password" autocomplete="new-password" placeholder="Enter a password">
    </label>
    <div class="pwsm-meter" aria-hidden="true">
      <div class="pwsm-fill"></div>
    </div>
    <div class="pwsm-label" aria-live="polite">Password strength</div>
    <span class="pwsm-words" hidden>
      <span data-level="empty">Password strength</span>
      <span data-level="weak">Weak</span>
      <span data-level="medium">Medium</span>
      <span data-level="strong">Strong</span>
    </span>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Level colours (CSS — --pwsm-weak, --pwsm-medium, --pwsm-strong on .fx-0286-root) #ef4444 · #f59e0b · #10b981 On white, darken them (#dc2626, #d97706, #059669) to keep the text readable.
Bar (CSS — --pwsm-bar-height, --pwsm-track) 4px · 10% white Bar thickness and the colour of its empty track.
Labels (HTML — .pwsm-words) Password strength · Weak · Medium · Strong Translate or reword here ("Too short", "Fair", "Excellent"): the script reads these texts again on every change.
Field (CSS — --pwsm-field, --pwsm-border, --pwsm-focus, --pwsm-text, --pwsm-muted) 5% white · 10% white · #6366f1 · #fff · #8b8b93 --pwsm-muted colours the text while the field is empty.
Sizes (CSS — --pwsm-width, --pwsm-font-size, --pwsm-label-size) 280px · 1rem · .75rem Width is a maximum; 100% follows the container. Enlarge the verdict for a presentation screen.
Demo frame (CSS — --pwsm-bg, --pwsm-min-height) #0a0a0f · 300px In a real form: --pwsm-bg:transparent; --pwsm-min-height:0.
Scoring (JS — score() function and thresholds in update()) 1 point per criterion, Weak ≤ 2, Medium = 3, Strong ≥ 4 To require 12 characters, replace pw.length >= 10 with pw.length >= 12.

FAQ

The effect blocks nothing by itself. Read its state on submit: form.addEventListener('submit', e => { if (group.dataset.strength !== 'strong') e.preventDefault(); }), where group is the field's .pwsm-group. Always check again on the server.
The scoring counts shape criteria (length, uppercase, digit, symbol) and knows no list of common passwords. For a real estimate, plug a library such as zxcvbn into score() and keep the effect's display.
After a form reset, yes, automatically. After a value set by script (a "Generate" button, a password manager that fires no event), call input.dispatchEvent(new Event('input', {bubbles: true})): the bar and the verdict are recalculated.