WEBLEB
Início
Editor
Entrar
Pro
Português
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Regras de senha + alternar componentes da Web
1749
Andev.web
Abrir no Editor
Publique Seu Código
Recomendado
10 June 2025
Um código de Mete
13 June 2025
Um Código de Metehan
26 May 2025
Um Código por mironovbogdan341
HTML
Copy
Andev Web
Password
Toggle password visibility
Longer than 8 characters
Includes a lowercase letter
Includes an uppercase letter
Includes a number
Includes a special character
CSS
Copy
.password-rules__meter { display: flex; align-items: center; gap: 0.25rem; max-inline-size: 10rem; } .password-rules__meter > :where(span) { width: 100%; height: 0.25em; background-color: lightgray; border-radius: 360px; transition: background-color 100ms ease-out; } password-rules[data-score="1"] .password-rules__meter :first-child, password-rules[data-score="2"] .password-rules__meter :nth-child(-n + 2), password-rules[data-score="3"] .password-rules__meter :nth-child(-n + 3), password-rules[data-score="4"] .password-rules__meter :nth-child(-n + 4) { background-color: dodgerblue; } password-rules[data-score="5"] .password-rules__meter :nth-child(-n + 5) { background-color: mediumseagreen; } .password-rules__score::before { display: block; counter-reset: score var(--score, 0) total var(--total, 5); content: counter(score) "/" counter(total); font-feature-settings: "tnum"; font-size: 0.8em; } .password-rules__checklist { --flow: 0.3rem; -webkit-padding-start: 1.2em; padding-inline-start: 1.2em; } .password-rules__checklist li { position: relative; list-style-type: circle; } .password-rules__checklist .is-match::before { content: "✅"; position: absolute; top: 0; right: calc(100% + 0.25em); font-size: 0.9em; } .password-input-wrapper { display: grid; grid-template-columns: 1fr auto; gap: 0.5rem; } .password-input-wrapper button { display: grid; place-items: center; } .password-input-wrapper button svg:last-of-type { display: none; } .password-input-wrapper button[aria-pressed="true"] { svg:first-of-type { display: none; } svg:last-of-type { display: block; } } /* Base elements */ body { font-family: system-ui, sans-serif; color: CanvasText; background: Canvas; } form { width: min(30rem, 100% - 1rem); margin-inline: auto; margin-block: 4rem; } input { box-sizing: border-box; padding-inline: 0.5rem; width: 100%; border: 1px solid lightgray; border-radius: 0.25rem; box-shadow: 0 2px 6px -4px rgba(0 0 0 / 0.2); } button { all: unset; outline: revert; padding-inline: 1rem; background: linear-gradient(white, whitesmoke); &:active { translate: 0 1px; box-shadow: none; } } :is(input, button) { font: inherit; padding-block: 0.5rem; border: 1px solid lightgray; border-radius: 0.25rem; box-shadow: 0 2px 6px -4px rgba(0 0 0 / 0.2); } /* Utils */ .flow > * + * { -webkit-margin-before: var(--flow, 1rem); margin-block-start: var(--flow, 1rem); } .visually-hidden { clip: rect(0 0 0 0); -webkit-clip-path: inset(50%); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; } .input-wrapper { display: grid; gap: 0.4rem; label { justify-self: start; } }
JS
Copy
class PasswordRules extends HTMLElement { connectedCallback() { this.input = document.getElementById(this.dataset.inputId); if (!this.input) return; this.rules = []; this.setupRules(); this.input.addEventListener("input", this); } handleEvent(e) { this.score = 0; for (let [index, rule] of this.rules.entries()) { const match = e.target.value.match(rule); if (match) this.score++; this.toggleMatchedRuleClass(index, match); } this.setAttributes("score", this.score); } setAttributes(name, value) { this.dataset[name] = value; this.style.setProperty(`--${name}`, value); } setupRules() { const rules = this.dataset.rules; if (!rules) return; rules.split(this.dataset.separator || ",").forEach((match) => { this.rules.push(new RegExp(match.trim())); }); this.setAttributes("total", this.rules.length); } toggleMatchedRuleClass(index, value) { const el = this.querySelector(`[data-rule-index="${index}"]`); if (!el) return; el.classList.toggle("is-match", value); } } class PasswordToggle extends HTMLElement { connectedCallback() { this.input = document.getElementById(this.dataset.inputId); this.status = document.getElementById(this.dataset.statusId); this.btn = this.querySelector("button"); if (!this.input || !this.btn) return; this.btn.ariaPressed = false; this.btn.ariaLabel = "Show password"; this.btn.setAttribute("aria-controls", this.dataset.inputId); this.btn.addEventListener("click", this); } handleEvent(e) { if (this.input.type === "password") { this.btn.ariaPressed = true; this.btn.ariaLabel = "Hide password"; this.input.type = "text"; if (this.status) this.status.textContent = "Password is showing"; } else { this.btn.ariaPressed = false; this.btn.ariaLabel = "Show password"; this.input.type = "password"; if (this.status) this.status.textContent = "Password is hidden"; } } } customElements.define("password-rules", PasswordRules); customElements.define("password-toggle", PasswordToggle);