Forms and input

Volunteer Signup Password Strength Feedback

Complete password strength feedback in a volunteer signup scenario: includes realistic content, actionable controls, clear status feedback, and responsive layouts across sizes.

Forms and inputPassword strength feedbackHTMLCSSJavaScript
With JavaScript enabled, you can edit, run, and save this example. The fixed source is as follows:
<!doctype html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Volunteer Signup Password Strength Feedback</title>
  <style>
    :root { --ink:#252525; --paper:#f7f2e8; --accent:#247ba0; --secondary:#f4b942; --line:color-mix(in srgb, var(--ink) 18%, transparent); --shadow:0 24px 60px color-mix(in srgb, var(--ink) 16%, transparent); color-scheme:light; }
    * { box-sizing:border-box; }
    html { min-width:320px; background:var(--paper); }
    body { min-height:100vh; margin:0; overflow-x:hidden; color:var(--ink); font-family:Baskerville,"Songti SC",serif; background:linear-gradient(90deg,var(--paper) 0 72%,color-mix(in srgb,var(--secondary) 18%,var(--paper)) 72%); }
    button,input,select,textarea { color:inherit; font:inherit; }
    button,[role="button"],input,select,textarea { accent-color:var(--accent); }
    button { cursor:pointer; }
    button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
    [hidden] { display:none !important; }
    @media (max-width:700px) { .mast h1 { line-height:1.08 !important; letter-spacing:-.035em !important; overflow-wrap:anywhere; } }
    @media (prefers-reduced-motion:reduce) { *,*::before,*::after { scroll-behavior:auto !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } }
    .page{width:min(1200px,calc(100% - 38px));margin:auto;padding:76px 0}.mast{display:grid;grid-template-columns:2fr 1fr;gap:7vw;align-items:center;margin-bottom:44px}.mast h1{font-family:Baskerville,"Songti SC",serif;font-weight:800;font-size:clamp(48px,11vw,112px);line-height:.86;letter-spacing:-.06em;margin:0}.eyebrow{display:block;margin-bottom:22px;color:var(--accent);font:800 11px/1 ui-monospace,monospace;letter-spacing:.26em}.intro{max-width:46ch;margin-top:26px;font-size:17px;line-height:1.85}.scenario{align-self:end;padding-bottom:14px;border-bottom:5px solid var(--accent);font-weight:800}.demo{border-radius:0 60px 0 0;box-shadow:-16px 18px 0 color-mix(in srgb,var(--accent) 22%,transparent);position:relative;min-height:460px;overflow:hidden;padding:clamp(30px,6vw,72px);background:color-mix(in srgb,var(--paper) 92%,#fff)}@media(max-width:700px){.page{width:calc(100% - 22px);padding:30px 0}.mast{grid-template-columns:1fr}.demo{padding:20px}}
    .panel{padding:24px;border-block:1px solid var(--ink);background:transparent}.stack{display:grid;gap:22px}.row{display:flex;flex-wrap:wrap;gap:16px}.action{padding:8px 0;border:0;border-bottom:1px solid currentColor;background:transparent;letter-spacing:.08em}.action.primary,.action.is-active{color:var(--accent);border-bottom-width:4px}.status{min-height:28px;margin-top:20px;font-style:italic}.metric{font-family:Didot,serif;font-size:clamp(38px,8vw,76px)}.muted{max-width:54ch;line-height:1.8}.meter{position:relative;height:3px;background:var(--line)}.meter>i{position:absolute;inset:0 auto 0 0;background:var(--accent)}.chip{padding-bottom:3px;border-bottom:1px solid var(--ink);font-size:13px}
    .composition-index{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:18px}.index-mark{display:grid;align-content:space-between;width:76px;padding:16px 10px;border:1px solid var(--line);color:var(--accent);background:color-mix(in srgb,var(--paper) 82%,transparent);text-align:center}.index-mark strong{font:900 34px/1 ui-monospace,monospace}.index-mark span{writing-mode:vertical-rl;font:800 10px/1.2 ui-monospace,monospace;letter-spacing:.18em}.composition-index .demo{grid-column:1;grid-row:1}.composition-index::before{content:"";position:absolute;left:-12px;top:38px;width:5px;height:45%;background:linear-gradient(var(--accent),var(--secondary))}@media(max-width:700px){.composition-index{grid-template-columns:1fr}.index-mark{grid-row:1;width:auto;grid-template-columns:auto 1fr}.index-mark span{writing-mode:horizontal-tb}.composition-index .demo{grid-row:2}}
    .password-lab{display:grid;gap:16px;max-width:650px;margin:auto}.password-lab h2{margin:.2em 0}.password-lab label{display:grid;gap:8px;font-weight:800}.password-wrap{display:grid;grid-template-columns:1fr auto}.password-wrap input,.password-wrap button{min-height:46px;padding:10px;border:1px solid var(--line);background:var(--paper)}.password-wrap input{border-radius:10px 0 0 10px}.password-wrap button{border-radius:0 10px 10px 0}.password-lab ul{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;padding:0;list-style:none}.password-lab li::before{content:"○ ";color:var(--line)}.password-lab li.is-met::before{content:"● ";color:var(--accent)}#passwordStrength i{width:0;transition:width .2s ease}@media(max-width:540px){.password-lab ul{grid-template-columns:1fr}}.workflow-dispatch{display:grid;grid-template-columns:minmax(210px,.48fr) minmax(0,1.52fr);gap:18px}.dispatch-console{display:grid;align-content:start;gap:16px;padding:22px;border:1px solid var(--line);border-radius:18px;background:color-mix(in srgb,var(--secondary) 12%,var(--paper))}.dispatch-console h2{margin:.2em 0}.dispatch-console form,.dispatch-console label{display:grid;gap:7px}.dispatch-console input,.dispatch-console select{min-width:0;width:100%;padding:10px;border:1px solid var(--line);border-radius:8px;background:var(--paper)}.dispatch-console fieldset{display:flex;gap:12px;border:1px solid var(--line);border-radius:10px}.dispatch-console fieldset label{display:flex;align-items:center}.dispatch-workbench{--dispatch-load:.22;min-width:0;padding:14px;border-left:8px solid color-mix(in srgb,var(--accent) calc(var(--dispatch-load)*100%),var(--line));background:linear-gradient(90deg,color-mix(in srgb,var(--accent) 8%,transparent),transparent 28%)}.dispatch-workbench[data-dispatch-priority="urgent"]{box-shadow:inset 0 0 0 2px var(--accent)}@media(max-width:900px){.workflow-dispatch{grid-template-columns:1fr}.dispatch-console{order:2}}
  </style>
</head>
<body data-aesthetic="magazine" data-composition="field-index">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">magazine / password strength feedback / INTERMEDIATE</span><h1>Volunteer Signup Password Strength Feedback</h1><p class="intro">Complete password strength feedback in a volunteer signup scenario: includes realistic content, actionable controls, clear status feedback, and responsive layouts across sizes.</p></div><span class="scenario">Volunteer Sign-Up</span></header>
    <div class="composition-index"><section class="demo" aria-label="Volunteer signup password strength feedback interactive area"><div class="workflow-dispatch"><aside class="dispatch-console"><span class="eyebrow">Volunteer Registration DISPATCH</span><h2>Volunteer scheduling dashboard</h2><form id="workflowDispatchForm"><label>Task Type<select id="workflowDispatchKind"><option>Check-in Guidance</option><option>Supplies Sorting</option><option>On-site assistance</option></select></label><label>Service hours<input id="workflowDispatchAmount" type="number" min="1" max="9999" value="27"><span>hour</span></label><fieldset><legend>Processing priority</legend><label><input type="radio" name="workflowPriority" value="normal" checked>Regular</label><label><input type="radio" name="workflowPriority" value="urgent">Urgent</label></fieldset><button class="action primary" type="submit">Accept scheduling</button></form><label>Current task<select id="workflowDispatchActive" aria-label="Switch current task"><option value="1">Check-in Guidance</option><option value="2">Supplies Sorting</option></select></label><output id="workflowDispatchSummary">Waiting for Dispatch</output></aside><section id="workflowCore" class="workflow-core dispatch-workbench" data-dispatch-priority="normal"><!-- 11DZ_CORE_START:forms-input-password-strength --><form id="passwordForm" class="password-lab panel"><span class="eyebrow">PASSWORD STRENGTH</span><h2>Volunteer Sign-up Security Passphrase</h2><label>New Password <span class="password-wrap"><input id="passwordInput" type="password" minlength="8" autocomplete="new-password" aria-describedby="passwordRules" required><button id="togglePassword" type="button" aria-pressed="false" data-core-bridge="forms-input-password-strength">Show</button></span></label><div id="passwordStrength" class="meter" role="progressbar" aria-label="Password strength" aria-valuemin="0" aria-valuemax="4" aria-valuenow="0"><i></i></div><ul id="passwordRules"><li data-rule="length">At least 8 characters</li><li data-rule="case">Includes uppercase and lowercase</li><li data-rule="number">At least one number</li><li data-rule="symbol">At least one symbol</li></ul><button class="action primary" type="submit">Check password strength</button></form><!-- 11DZ_CORE_END --></section></div><p id="status" class="status" role="status" aria-live="polite"></p></section><aside class="index-mark" aria-hidden="true"><strong>05</strong><span>Volunteer Signup FIELD INDEX</span></aside></div>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:forms-input-password-strength */
const passwordInput=document.querySelector('#passwordInput');const passwordMeter=document.querySelector('#passwordStrength');const passwordRules={length:value=>value.length>=8,case:value=>/[a-z]/.test(value)&&/[A-Z]/.test(value),number:value=>/\d/.test(value),symbol:value=>/[^a-z0-9]/i.test(value)};function scorePassword(){const value=passwordInput.value;let score=0;Object.entries(passwordRules).forEach(([name,test])=>{const met=test(value);document.querySelector('[data-rule="'+name+'"]').classList.toggle('is-met',met);if(met)score+=1;});passwordMeter.setAttribute('aria-valuenow',String(score));passwordMeter.querySelector('i').style.width=(score/4*100)+'%';announce('Password strength '+score+' / 4');return score;}passwordInput.addEventListener('input',scorePassword);document.querySelector('#togglePassword').addEventListener('click',event=>{const visible=passwordInput.type==='text';passwordInput.type=visible?'password':'text';event.currentTarget.setAttribute('aria-pressed',String(!visible));event.currentTarget.textContent=visible?'Show':'Hide';});document.querySelector('#passwordForm').addEventListener('submit',event=>{event.preventDefault();announce(scorePassword()===4?'Password passed local strength check':'Please satisfy all password rules');});
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"forms-input-password-strength","selector":"[data-core-bridge=\"forms-input-password-strength\"]","mode":"click","key":"Enter"};const workflowBridgeCore=document.querySelector('#workflowCore');const workflowBridgeControl=workflowBridgeCore.querySelector(workflowBridgeSpec.selector);if(!workflowBridgeControl)throw new Error('Missing core bridge: '+workflowBridgeSpec.name);const workflowBridgeControlledId=workflowBridgeControl.getAttribute('aria-controls');const workflowBridgeControlled=workflowBridgeControlledId?document.getElementById(workflowBridgeControlledId):null;workflowBridgeCore.dataset.workflowBridge=workflowBridgeSpec.name;workflowBridgeCore.dataset.workflowVersion='0';function workflowBridgeSerialize(){const visualNode=workflowBridgeCore.firstElementChild||workflowBridgeCore;const visual=getComputedStyle(visualNode);const outputs=[...workflowBridgeCore.querySelectorAll('output,[role="status"],[aria-live],meter,progress')].map(node=>node.textContent.trim()+'|'+node.getAttribute('aria-valuenow')+'|'+node.getAttribute('value'));const canvas=[...workflowBridgeCore.querySelectorAll('canvas')].map(node=>{try{return node.toDataURL().slice(-160);}catch{return 'canvas-unavailable';}});return JSON.stringify({html:workflowBridgeCore.innerHTML,status:statusOutput.textContent,outputs,canvas,visual:[visual.display,visual.visibility,visual.opacity,visual.transform,visual.filter,visual.backgroundColor,visual.width,visual.height],scroll:workflowBridgeSpec.mode==='scroll'?workflowBridgeControl.scrollTop:null});}let workflowBridgeLastEffect=workflowBridgeSerialize();function workflowBridgeSummary(){const label=(workflowBridgeControl.getAttribute('aria-label')||workflowBridgeControl.textContent||workflowBridgeControl.value||workflowBridgeSpec.name).trim().replace(/\s+/g,' ').slice(0,72);return label+' · Core Version '+workflowBridgeCore.dataset.workflowVersion;}function workflowBridgeCommit(){const effect=workflowBridgeSerialize();if(effect===workflowBridgeLastEffect)return {changed:false,summary:workflowBridgeSummary()};workflowBridgeLastEffect=effect;workflowBridgeCore.dataset.workflowVersion=String(Number(workflowBridgeCore.dataset.workflowVersion||0)+1);return {changed:true,summary:workflowBridgeSummary()};}function workflowBridgeScheduleCommit(){queueMicrotask(workflowBridgeCommit);setTimeout(workflowBridgeCommit,0);}workflowBridgeControl.addEventListener("click",workflowBridgeScheduleCommit);const workflowBridgeStateTargets=new Set(workflowBridgeCore.querySelectorAll('dialog'));if(workflowBridgeControlled&&workflowBridgeCore.contains(workflowBridgeControlled))workflowBridgeStateTargets.add(workflowBridgeControlled);workflowBridgeStateTargets.forEach(target=>['close','cancel','toggle'].forEach(eventName=>target.addEventListener(eventName,workflowBridgeScheduleCommit)));function workflowBridgeActivate(){workflowBridgeControl.focus();workflowBridgeControl.click();const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowDispatchCore=document.querySelector('#workflowCore');const workflowDispatchForm=document.querySelector('#workflowDispatchForm');const workflowDispatchSelect=document.querySelector('#workflowDispatchActive');const workflowDispatchJobs=new Map([["1",{"label":"Check-in Guidance","amount":12,"priority":"normal","touches":0}],["2",{"label":"Supplies Sorting","amount":21,"priority":"urgent","touches":0}]]);let workflowDispatchSerial=workflowDispatchJobs.size;function workflowDispatchDrive(job,activate=false){workflowDispatchCore.dataset.dispatchPriority=job.priority;workflowDispatchCore.style.setProperty('--dispatch-load',Math.min(.95,.16+job.amount/120));const bridge=activate?workflowBridgeActivate():{changed:false,summary:workflowBridgeSummary()};document.querySelector('#workflowDispatchSummary').textContent=job.label+' · '+job.amount+' hours · '+bridge.summary;announce('Volunteer scheduling current task:'+job.label);}function workflowDispatchRender(activeId,activate=false){workflowDispatchSelect.replaceChildren(...[...workflowDispatchJobs].map(([id,job])=>{const option=document.createElement('option');option.value=id;option.textContent=job.label+(job.priority==='urgent'?' · Urgent':'');return option;}));workflowDispatchSelect.value=activeId;workflowDispatchDrive(workflowDispatchJobs.get(activeId),activate);}workflowDispatchForm.addEventListener('submit',event=>{event.preventDefault();const data=new FormData(workflowDispatchForm);const id=String(++workflowDispatchSerial);workflowDispatchJobs.set(id,{label:document.querySelector('#workflowDispatchKind').value,amount:Math.max(1,Number(document.querySelector('#workflowDispatchAmount').value)||1),priority:data.get('workflowPriority'),touches:0});workflowDispatchRender(id,true);});workflowDispatchSelect.addEventListener('change',()=>workflowDispatchDrive(workflowDispatchJobs.get(workflowDispatchSelect.value),true));workflowDispatchCore.addEventListener('focusin',()=>{const job=workflowDispatchJobs.get(workflowDispatchSelect.value);if(!job)return;job.touches+=1;document.querySelector('#workflowDispatchSummary').textContent=job.label+' · '+job.amount+' hours · '+workflowBridgeSummary();});workflowDispatchRender('1',false);
workflowBridgeReset();
  </script>
</body>
</html>
Page feedbackFound an issue or have suggestions for improvement?
Feedback features need to be used in the online version

Please enable JavaScript in the online version before submitting; local features of the current tool or example are not affected.

Go to the online version for feedback