skip to content

Autofill and autocomplete Tokens

The autocomplete attribute is a defined vocabulary, not a boolean, and using the right tokens is what makes browsers and password managers fill checkout and login forms correctly. Interviewers ask why autocomplete=off on a password field is usually the wrong call.

part ofHTMLoverview, primer and where to startread it →
on this pageshow

questions

5

The HTML autocomplete attribute accepts more than "on" and "off". What is its token vocabulary, and what would you put on the name, email and address inputs of a checkout form?

level: juniorimportance: must knowfreq 65%

answer

  1. not a boolean
  2. a fixed list of field names
  3. given-name, street-address, postal-code
  4. "on" only permits, it does not describe
  5. WCAG 1.3.5 Identify Input Purpose

basics

~20 s

autocomplete takes a defined vocabulary of field-name tokens — name, email, tel, street-address, address-level2, postal-code, country, cc-number — not just on/off. The token tells the browser what a field means so autofill fills it correctly.

solid answer

~40 s

`autocomplete` is not a boolean. HTML defines a fixed vocabulary of autofill field names, and the value you write names what the field collects: `name` (or `given-name` / `family-name`), `email`, `tel`, `organization`, `street-address` or `address-line1` / `address-line2`, `address-level2` for the city, `address-level1` for the state or region, `postal-code`, `country-name`, and the payment set `cc-name`, `cc-number`, `cc-exp`, `cc-csc`. Writing `autocomplete="on"` only permits autofill — the browser still has to guess the meaning from the `name`, `id`, `label` and placeholder text, which is exactly what breaks on design-system markup with generated ids or non-English labels. A token removes the guess. It is also how you satisfy WCAG 2.1 success criterion 1.3.5, Identify Input Purpose, which requires the purpose of inputs collecting the user's own data to be programmatically determinable.

code

html · 21 lines
html
<form method="post" action="/checkout">
  <label for="fn">First name</label>
  <input id="fn" name="fn" autocomplete="given-name">

  <label for="ln">Last name</label>
  <input id="ln" name="ln" autocomplete="family-name">

  <label for="em">Email</label>
  <input id="em" name="em" type="email" autocomplete="email">

  <label for="st">Street address</label>
  <input id="st" name="st" autocomplete="street-address">

  <label for="ct">City</label>
  <input id="ct" name="ct" autocomplete="address-level2">

  <label for="pc">Postal code</label>
  <input id="pc" name="pc" autocomplete="postal-code">

  <button>Continue</button>
</form>

go deeper

for a junior

Know that autocomplete takes named tokens and be able to say a handful from memory — given-name, family-name, email, tel, street-address, postal-code, cc-number — and put them on a form without inventing spellings.

for a middle

Explain what the browser does when the token is absent: heuristics over name, id, label and placeholder that fail on generated ids and non-English labels. Be clear that "on" permits autofill but describes nothing.

for a senior

Show you treat autofill correctness as a product metric on checkout and sign-up flows, and that you audit a design system's input component so the token is a first-class prop rather than something each team remembers to pass.

for a principal

Own the tradeoff between a component library that hides markup and the per-field metadata autofill needs. Decide where the tokens live, how they are reviewed, and how you tie WCAG 1.3.5 conformance to that same mechanism instead of a separate checklist.

## The attribute is a vocabulary, not a switch Most people first meet `autocomplete` as `autocomplete="off"`, which makes it look like a boolean toggle. It is not. The HTML standard defines a closed list of **autofill field names** — tokens such as `name`, `email`, `street-address`, `postal-code`, `cc-number` — and the value of the attribute is drawn from that list. The token is a machine-readable statement of *what this field is for*, addressed to the browser and to any password manager or assistive technology reading the form. The attribute is valid on `<input>` (for the text-like types), `<textarea>`, `<select>`, and on `<form>` itself, where it sets the default for the controls inside it. ## The token grammar A full value has up to four parts, in a fixed order: ``` [section-*] [shipping|billing] [home|work|mobile|fax|pager] field-name ``` Only the field name is required, so the everyday case is a single token. The optional pieces group fields: `shipping street-address` and `billing street-address` describe two different addresses in one form, and a `section-*` prefix creates an arbitrary named group when you have two of the same kind of thing on one page. ## The tokens you actually use Identity and contact: `name`, or the split forms `given-name`, `family-name`, `additional-name`, `honorific-prefix`; `nickname`, `username`, `organization`, `organization-title`, `email`, `tel`, `url`, `bday`. Address: `street-address` for a single multi-line field, or `address-line1` / `address-line2` / `address-line3` when it is split; `address-level2` for the city or town, `address-level1` for the state, province or region; `postal-code`; `country` for the two-letter code and `country-name` for the human-readable name. Payment: `cc-name`, `cc-number`, `cc-exp` (or `cc-exp-month` and `cc-exp-year`), `cc-csc`, `cc-type`. Credentials and codes: `username`, `current-password`, `new-password`, `one-time-code`. A typical checkout block looks like this: ```html <label for="fname">First name</label> <input id="fname" name="fname" autocomplete="given-name"> <label for="email">Email</label> <input id="email" name="email" type="email" autocomplete="email"> <label for="addr">Street address</label> <input id="addr" name="addr" autocomplete="street-address"> <label for="city">City</label> <input id="city" name="city" autocomplete="address-level2"> <label for="zip">Postal code</label> <input id="zip" name="zip" autocomplete="postal-code"> ``` ## What happens when you leave the token off The browser does not give up — it guesses. It runs heuristics over the control's `name` and `id`, the text of its label, its placeholder and its position among neighbouring fields. Those heuristics work well on conventional English markup (`name="email"`) and poorly everywhere else: framework-generated ids like `id="input-7a3f"`, class-name-driven markup, minified attribute names, labels in a language the heuristic was not tuned for, or a two-line address split in an unusual way. A guess that lands wrong is worse than no fill — the user's postcode ends up in the city field and they now have to clear it. Writing `autocomplete="on"` does not fix this. `on` only says "autofill is permitted here", which is already the default; the browser still has to work out the meaning. Only a field-name token communicates meaning. ## Why it is worth the attributes Three separate payoffs. First, completion speed: a checkout that fills in one tap has measurably less abandonment than one typed on a phone keyboard. Second, correctness: the browser stores structured profile data, so a correctly tokenised form gets the right subfield in the right box instead of a fuzzy match. Third, accessibility: WCAG 2.1 added success criterion 1.3.5, *Identify Input Purpose* (Level AA), which requires that the purpose of a field collecting information about the user be programmatically determinable. In HTML the way you satisfy it is precisely these tokens — they let assistive technology and personalisation tools relabel a field with a familiar word or icon for users who need that. ## Common mistakes Inventing tokens. `autocomplete="firstname"` or `autocomplete="zip"` are not in the vocabulary; an unrecognised token is treated as if you had written `on`, so you get the guessing behaviour back without noticing. Use `given-name` and `postal-code`. Confusing the token with the input type. `type` controls the keyboard, the built-in validation and the widget; `autocomplete` controls what value gets suggested. `type="email" autocomplete="email"` is normal and correct — they are answering different questions. Confusing it with `name`. The `name` attribute is what your server sees on submission; the autocomplete token is what the browser sees. They are independent, and you should not rename your form fields to make heuristics work when a token states it outright. Finally, remember the vocabulary is fixed and small. If nothing in it describes your field — an internal reference number, a free-text note — then the honest answer is that no token applies, and you simply omit the attribute.

  • If you write a token the browser does not recognise, such as autocomplete="zipcode", what happens?
    An unrecognised token is not an error you will see. The browser cannot map it to a known autofill field, so it falls back to treating the field as if autofill were simply enabled and resumes guessing from the `name`, `id` and label. The failure is silent, which is why invented tokens survive in codebases for years. Use the spec spelling — `postal-code`, not `zipcode`.
  • How does the autocomplete token relate to the input's type and name attributes?
    They are three independent channels. `type` decides the widget, the on-screen keyboard and the built-in validation. `name` is the key your server receives on submission. `autocomplete` describes the field's meaning to the browser's autofill store. `<input type="tel" name="contactPhone" autocomplete="tel">` sets all three deliberately, and none of them can substitute for another.
  • Can autocomplete be set on the form element rather than on every input?
    Yes, but only usefully as `autocomplete="on"` or `"off"`, which becomes the default state for the controls inside it. Field-name tokens are inherently per-field — the form does not know which of its inputs is the postcode. So a form-level value is a coarse switch, and the descriptive tokens still have to go on each control.

saying these in an interview costs you the question

  • Says autocomplete is just on or off
  • Invents tokens like firstname or zip
  • Claims autocomplete="on" tells the browser what the field means
  • Thinks the name attribute is what autofill reads
  • Confuses the autocomplete token with the input type

context

open as a page

On a login form and on a change-password form, which HTML autocomplete values belong on the password inputs, and what does autocomplete="new-password" change?

level: middleimportance: must knowfreq 60%

basics

~20 s

Login uses autocomplete="username" plus autocomplete="current-password". A change-password form uses current-password for the old value and new-password on both the new and confirm fields, which tells the browser to offer a generated password instead of filling the stored one.

open as a page

Your app asks the user to type a six-digit code sent by SMS. Which HTML autocomplete value makes phones offer that code, and how should the input be marked up?

level: middleimportance: should knowfreq 40%

basics

~20 s

Use a single input with autocomplete="one-time-code". That token lets mobile browsers surface a code just received by SMS as a one-tap suggestion. Splitting the code across six separate boxes defeats it, because the token describes one whole code.

open as a page

A reviewer asks you to put autocomplete="off" on the password input of your site's login form. Why is that usually the wrong call, and what do browsers actually do with it?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Mainstream browsers deliberately ignore autocomplete="off" on password fields and still offer to save and fill credentials, so the attribute mostly fails to do what the reviewer wants while making the form worse for people relying on a password manager.

open as a page

A checkout page collects a shipping address and a billing address, each with its own street and postal-code inputs. How do you write the autocomplete attributes so the browser fills the two groups separately?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Prefix the field name with a grouping token: autocomplete="shipping street-address" on one group and autocomplete="billing street-address" on the other. For two groups of the same kind, add a section-* prefix such as section-gift shipping street-address.

open as a page