HTML Input Type Password
Every account on the web starts with a password box. It looks simple: a text field that shows dots instead of letters. But this one little input sits on the front line of security, and small mistakes in how you build it can lock people out, or let attackers in.
In this lesson, you will learn what type="password" really does (and what it does not do), how to help browsers and password managers work with it, how to add an accessible "show password" button, and which habits keep your visitors safe.
What You Will Learnβ
- What
type="password"does and what it does not protect - The right
autocompletevalues for sign-in and sign-up forms - How to build an accessible show/hide toggle
- Which attributes apply, and which rules help instead of hurt
- How password managers and paste behave, and why you must not block them
- Security basics for the server side, and common mistakes
The Basicsβ
- HTML Code
- Browser Output
<label for="pw">Password</label>
<input type="password" id="pw" name="password" />
Type in the box and you see dots (or asterisks), not letters. That is all type="password" changes on screen: the characters are masked, so someone looking over your shoulder cannot read them.
It also tells the browser, password managers, and assistive tools: "this field holds a secret." Browsers will offer to save it, managers will offer to fill it, and some will refuse to copy the masked text out of the field.
What Password Does Not Doβ
type="password" only hides the characters on the screen. It does not encrypt anything. When the form is submitted, the value travels as plain text, such as password=secret123. Only HTTPS protects it on the way to the server.
| Myth | Reality |
|---|---|
| "The browser encrypts it" | No. It only hides the characters on screen |
| "It is safe on any page" | Only safe on a page served over HTTPS |
| "Hidden means unreadable" | The value is still readable by scripts on the page and by browser tools |
| "The server gets a hashed value" | The server receives the plain password, and it must hash it before storing |
So, always serve any page with a password field over HTTPS, and always use method="post". A GET form would put the password into the web address, and from there into history, logs, and shared links.
<form action="/login" method="post">
<!-- never method="get" for a password -->
</form>
Attributes for Password Inputsβ
| Attribute | What it does | Example |
|---|---|---|
name | The key sent to the server | name="password" |
id | Connects the label | id="pw" |
autocomplete | Tells the browser which password this is | autocomplete="current-password" |
required | Cannot be left empty | required |
minlength | Fewest characters accepted | minlength="12" |
maxlength | Most characters accepted | maxlength="128" |
pattern | Must match a regular expression | pattern=".{12,}" |
placeholder | Hint text (never a substitute for a label) | placeholder="At least 12 characters" |
readonly, disabled | Behavior flags, as with any input | disabled |
autofocus | Focus on load | autofocus |
inputmode | On-screen keyboard hint | inputmode="text" |
Three things stand out here:
valueis rarely used. Do not pre-fill a password, and never print a user's password back into a page.sizeandlistdo not apply to passwords.autocapitalize="none"andspellcheck="false"are sensible on phones. Most browsers already handle this for password fields, but it is harmless to be explicit.
Autocomplete: The Most Important Attributeβ
Password managers and browser autofill rely on autocomplete to know what a field means. There are two main values, and they are not interchangeable.
| Situation | Value | What happens |
|---|---|---|
| Signing in | current-password | The manager offers a saved password |
| Creating or changing a password | new-password | The manager offers to generate a strong one, and to save it |
| One-time code (SMS or app) | one-time-code | Phones can read the code from a message |
- HTML Code
- Browser Output
<form action="/login" method="post">
<label for="email">Email</label>
<input type="email" id="email" name="email" autocomplete="username" required />
<label for="pw">Password</label>
<input
type="password"
id="pw"
name="password"
autocomplete="current-password"
required
/>
<button type="submit">Sign in</button>
</form>
<form action="/signup" method="post">
<label for="new-email">Email</label>
<input type="email" id="new-email" name="email" autocomplete="username" required />
<label for="new-pw">Choose a password</label>
<input
type="password"
id="new-pw"
name="password"
autocomplete="new-password"
minlength="12"
required
/>
<button type="submit">Create account</button>
</form>
Note that the email field uses autocomplete="username". Password managers look for a username next to the password, so they know which account the password belongs to, even when the "username" is an email address.
With autocomplete="new-password", browsers suggest a long random password and remember it for the visitor. That is a security gain for them, so never fight it.
A Show-Password Toggleβ
Masked text makes typing hard, especially on phones. Mistakes are invisible, so people give up or pick weaker passwords. A show password button solves this.
The idea: a button switches the input between type="password" and type="text". Try it below.
- HTML Code
- Browser Output
<label for="pw">Password</label>
<input type="password" id="pw" name="password" autocomplete="current-password" />
<button type="button" id="toggle" aria-pressed="false" aria-controls="pw">
Show password
</button>
const input = document.getElementById("pw");
const toggle = document.getElementById("toggle");
toggle.addEventListener("click", () => {
const show = input.type === "password";
input.type = show ? "text" : "password";
toggle.setAttribute("aria-pressed", String(show));
toggle.textContent = show ? "Hide password" : "Show password";
});
What makes this toggle accessible:
- It is a real
<button type="button">, so keyboards and screen readers work with it, and it does not submit the form. type="button"matters. A button inside a form defaults tosubmit.- It has a text label ("Show password"), not just an eye icon. If you use an icon, add a text alternative.
aria-pressedtells screen readers whether the password is currently shown.aria-controlslinks the button to the field it changes.
Some browsers add their own show/hide eye to password fields. If you build your own, you may see two buttons. You can hide the browser's with CSS (input::-ms-reveal { display: none; } on Edge), but keep one working toggle for every visitor.
Helping People Choose a Good Passwordβ
Show the Rules Up Frontβ
Do not wait for a failed submit to explain the rules. Put them in text, near the field, and link them with aria-describedby.
- HTML Code
- Browser Output
<label for="new-pw">Create a password</label>
<input
type="password"
id="new-pw"
name="password"
autocomplete="new-password"
minlength="12"
required
aria-describedby="pw-hint"
/>
<p id="pw-hint">Use at least 12 characters. A phrase of several words works well.</p>
The checklist above updates as you type. (That part uses JavaScript. The HTML alone needs only minlength and a hint.)
What Good Rules Look Likeβ
Security guidance (such as the NIST recommendations) has moved away from the old "one capital, one number, one symbol" rules. Those rules make people choose passwords like Password1!, which are weak and easy to guess.
| Do | Don't |
|---|---|
| Require a minimum length (12 or more is a good start) | Force strange character mixes |
| Allow long passwords and passphrases (at least 64 characters) | Set a small maxlength such as 12 |
| Allow every character, including spaces and Unicode | Reject symbols, spaces, or accented letters |
| Check against lists of common or leaked passwords on the server | Force a password change every month |
| Let people paste | Block paste, which breaks password managers |
Unlike a username, a password must be used exactly as typed. If someone chooses a password that begins with a space, the server must keep it. Hash and compare the value as it is.
Confirm Password: Is It Needed?β
Many sign-up forms ask visitors to type the password twice. With a show-password button, or a password manager that fills the field for them, this second box is often unnecessary, and adds friction. If you do use one:
<label for="pw1">New password</label>
<input type="password" id="pw1" name="password" autocomplete="new-password" required />
<label for="pw2">Confirm new password</label>
<input type="password" id="pw2" name="password2" autocomplete="new-password" required />
HTML cannot compare two fields on its own. A little JavaScript can (using setCustomValidity, which you will meet in Form Validation), and the server must always check again.
Password Managers and Pasteβ
A password manager is a tool that creates, stores, and fills strong, unique passwords. Millions of people use one, and it is one of the best things they can do for their security. Help it work:
- Use
type="password"and the correctautocompletevalues. - Keep the username and password fields in the same form, and use ordinary inputs, not custom widgets.
- Do not block pasting, with
onpaste="return false"or similar. This used to be a common "security" idea, and it makes things worse, because it punishes the people who use managers. - Do not change field names on every page load, which confuses autofill.
- Use separate, real pages (or forms) for sign-in and sign-up, so the browser knows which is which.
Styling a Password Inputβ
input[type="password"] {
width: 100%;
max-width: 24rem;
padding: 0.6rem 0.75rem;
border: 1px solid #64748b;
border-radius: 6px;
font: inherit;
font-size: 1rem;
}
input[type="password"]:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 2px;
}
- Keep the same look as your other fields, so the form feels consistent.
- Keep a visible focus style.
- If you place a show/hide button inside the field with CSS, leave enough right padding so long passwords do not slide under it.
Accessibility at a Glanceβ
- Always add a visible label. "Password" is clear, and a placeholder cannot replace it.
- Use
autocomplete, so people who struggle to type can have it filled for them. - State the rules in text before the visitor submits, and link them with
aria-describedby. - Offer a show/hide button that works with a keyboard and a screen reader.
- Do not block paste.
- Give clear errors: which field, what is wrong, and how to fix it. For a failed sign-in, say something like "That email or password is not right," which does not reveal which one was wrong.
- Avoid time limits and "type it again to continue" tricks that make life hard for people who type slowly.
- Offer alternatives when you can, such as passkeys, "sign in with a link sent by email," or single sign-on.
Security Notesβ
HTML is only the front door. The real security happens on the server.
- Use HTTPS everywhere. A password sent over plain HTTP can be read by anyone on the network.
- Use
method="post". Never put a password in a URL. - Hash passwords on the server with a slow, purpose-built algorithm (such as Argon2id, bcrypt, or scrypt), with a unique salt. Never store the plain password, and never use plain MD5 or SHA-1.
- Never send a password back in a page, an email, or a log file.
- Limit attempts, and add other protections such as rate limiting, to stop guessing attacks.
- Offer two-factor authentication (or passkeys) for important accounts.
- Check for common and leaked passwords, and refuse them.
You will see more in Secure Form Design.
Global Audience Notesβ
- Do not restrict characters. People around the world type passwords with accents, non-Latin scripts, and spaces.
- Count carefully. A character may be one or several bytes. Set server limits generously, and compare Unicode in a consistent way (normalize it).
- Remember different keyboards. A visitor on an unfamiliar keyboard layout may find symbols hard to type. A show-password button helps, and so does a long passphrase of ordinary words.
- Write clear, simple rules that translate well, and place them near the field.
- Think of shared computers and slow connections. Keep the page light and the form quick.
Common Mistakes to Avoidβ
- Using
type="text"for a password. The characters show on screen. - Using
method="get", which puts the password in the URL. - Serving the form over plain HTTP.
- Wrong or missing
autocomplete. Usecurrent-passwordto sign in, andnew-passwordto sign up. - Blocking paste, which breaks password managers.
- A small
maxlength, such as 12 or 16, which prevents passphrases. - Rules that reject spaces or symbols, or force odd character mixes.
- Trimming or changing the password on the server.
- Pre-filling
valueor echoing the password back into the page. - Forgetting
type="button"on the show/hide button, so it submits the form. - A toggle that is only an icon, with no text alternative.
- Telling attackers too much, such as "No account with that email," instead of one general error message.
Practice Timeβ
Try these in your editor:
- Build a sign-in form with an email field and a password field, both labeled.
- Add
autocomplete="username"andautocomplete="current-password", and see whether your browser offers to save the password. - Build a sign-up form with
autocomplete="new-password"andminlength="12", and submit a short password to see the browser's message. - Add a "Show password" button that switches between
passwordandtext. - Add
aria-pressedand update it when the button is clicked. - Link a hint to the field with
aria-describedby. - Change the form to
method="get"and submit it. Notice the password in the address bar, then change it back topost. - Try pasting into the field. Make sure nothing blocks it.
- Add a "Confirm password" field, and compare the two values with JavaScript.
- Bonus: write down three server-side steps that keep passwords safe.
Quick Recapβ
Click a question to check your answer.
1. What does type="password" actually do?
It masks the characters on screen, and tells browsers and password managers that the field holds a secret. It does not encrypt the value.
2. How is a password protected on its way to the server?
Only by HTTPS. Without it, the value is sent as plain text that others on the network may read.
3. Which autocomplete values should you use for sign-in and sign-up?
current-password for signing in, and new-password for creating or changing a password. The second lets managers suggest a strong password.
4. Why must the show-password button have type="button"?
Inside a form, a button defaults to submit. Without type="button", clicking "Show password" would submit the form.
5. Why is blocking paste a bad idea?
It breaks password managers, which paste long, unique passwords. It pushes people toward short, reused ones, which is less secure.
6. Should the server trim a password?
No. A password must be used exactly as typed, including any spaces. Hash it with a slow algorithm such as Argon2id or bcrypt before storing it.
Key Takeawaysβ
type="password"masks characters on screen. It does not encrypt, so use HTTPS andmethod="post".- Use
autocomplete="current-password"to sign in andautocomplete="new-password"to sign up, withautocomplete="username"on the account field. - Offer an accessible show/hide button: a real
<button type="button">, with a text label andaria-pressed. - Prefer a good minimum length and long limits over odd character rules. Allow every character, and allow pasting.
- Do not trim, pre-fill, or echo passwords. On the server, hash them with Argon2id, bcrypt, or scrypt.
- Show the rules before the visitor submits, and keep error messages clear but not revealing.
You now know how to handle secrets. Next, learn the type that checks addresses for you, in Email, or return to the Forms overview.