Modern HTML5 in Production · Forms That Work
Autocomplete, Input Types and Mobile Keyboards
Why mobile checkout conversion was low and password managers didn't work on the login page, and how type, autocomplete and inputmode fix data entry.
Scenario
Example app: to stop "browsers filling things in wrong", a developer adds autocomplete="off" to the login and checkout forms. Phone and card fields are type="text", and the postcode field uses type="number".
What you see in production
- Mobile checkout conversion is far below desktop. Session recordings show users switching keyboards to type digits.
- Password managers don't offer to fill the login form, so users reuse weak passwords or abandon login.
- Postcodes with leading zeros lose them ("02134" becomes "2134"), and some UK postcodes can't be entered at all.
The naive code
<form autocomplete="off">
<input type="text" name="phone">
<input type="number" name="postcode">
<input type="text" name="card">
</form>
Reproduce it
The preview shows the improved form. On a phone, each field opens the right keyboard, and browsers and password managers can fill it. Compare the attributes with the naive form above.
<style> label { display: block; margin-top: 8px; font-weight: 600; } input { font-size: 16px; } </style>
<form id="checkout" novalidate>
<label for="email">Email</label>
<input id="email" type="email" autocomplete="email">
<label for="phone">Phone</label>
<input id="phone" type="tel" autocomplete="tel">
<label for="postcode">Postcode</label>
<input id="postcode" type="text" autocomplete="postal-code" inputmode="text" autocapitalize="characters">
<label for="cc">Card number</label>
<input id="cc" type="text" inputmode="numeric" autocomplete="cc-number" pattern="[0-9 ]{12,23}">
<label for="code">One-time code</label>
<input id="code" type="text" inputmode="numeric" autocomplete="one-time-code" maxlength="6">
<p><button>Pay</button> <span id="out"></span></p>
</form>
<script>
// Real pages use the form's "submit" event; this preview blocks form submission, so we listen for the click.
document.querySelector("#checkout button").addEventListener("click", (e) => {
e.preventDefault();
document.getElementById("out").textContent = "postcode kept as text: '" + document.getElementById("postcode").value + "'";
});
</script>
Root cause
autocomplete="off"blocks the browser's autofill and discourages password managers, which slows users down and pushes them toward weak passwords. (Many browsers ignore it for login fields anyway.)type="text"gives phones a general keyboard.type="number"is for quantities, not identifiers: it strips leading zeros, allowse, and changes the value on scroll.
The fix
- Use precise
autocompletetokens:email,name,tel,street-address,postal-code,cc-number,cc-exp,username,current-password,new-password,one-time-code. - Choose types by meaning:
email,tel,url,search,date. Usetype="number"only for real numbers you'd do arithmetic on. - For numeric identifiers (card numbers, postcodes in some countries, codes), use
type="text"withinputmode(numeric,decimal,tel,email) to get the right keyboard without number semantics. - Use 16px or larger inputs on mobile so browsers don't zoom on focus.
Trade-offs
- Autofill can occasionally fill a wrong field when names are ambiguous; precise
autocompletetokens fix that better than turning autofill off. - Card fields from payment providers (iframes) set these attributes for you.
Detect it in production
- Compare mobile and desktop completion rates per field; long time-to-complete on short fields suggests the wrong keyboard.
- Test login with the major password managers on each release.
Key points
- Don't disable autocomplete; use precise autocomplete tokens.
- Pick input
typeby meaning; useinputmodefor numeric identifiers instead oftype="number". - Good attributes speed up mobile forms and make password managers work.
Practice questions
Why is autocomplete="off" on a login form harmful?
Answer
It discourages password managers and autofill, pushing users to type and reuse weak passwords and slowing them down. Use autocomplete="username" and "current-password" (or "new-password" on sign-up) instead.
When should you use type="number" and when inputmode="numeric"?
Answer
type="number" for quantities you do arithmetic on. For numeric identifiers (card numbers, codes, some postcodes), use type="text" with inputmode="numeric": it shows a numeric keyboard without stripping leading zeros or accepting exponents.
What does autocomplete="one-time-code" do?
Answer
It tells browsers the field expects a one-time code, so mobile operating systems can offer the code from an SMS or authenticator for one-tap filling.
Open in the app to mark lessons complete, take notes and track your progress.