skip to content

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%

answer

  1. two addresses look identical to the browser
  2. tokens before the field name
  3. two modes only, and they are fixed
  4. invent your own group name
  5. order is fixed, not free

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.

solid answer

~50 s

The autofill vocabulary is not just field names — a value may carry grouping tokens before the field name, in a fixed order: an optional `section-*` prefix, then `shipping` or `billing`, then for contact fields `home` / `work` / `mobile`, then the field name itself. So the shipping block reads `shipping street-address`, `shipping address-level2`, `shipping postal-code`, and the billing block reads `billing street-address`, `billing address-level2`, `billing postal-code`. Without the prefixes both blocks look identical to the browser, which is why the classic bug is one saved address landing in both. If you need two groups of the *same* mode — say two shipping addresses on a gift order — use an arbitrary `section-*` name to distinguish them: `section-gift shipping street-address` versus `section-home shipping street-address`. The order is fixed; `shipping section-gift street-address` is not a valid value. Suppressing autofill with `off` on the second block is the wrong fix — it removes help rather than describing the field.

code

html · 13 lines
html
<fieldset>
  <legend>Deliver to</legend>
  <input name="ship_street" autocomplete="shipping street-address">
  <input name="ship_city"   autocomplete="shipping address-level2">
  <input name="ship_zip"    autocomplete="shipping postal-code">
</fieldset>

<fieldset>
  <legend>Billing address</legend>
  <input name="bill_street" autocomplete="billing street-address">
  <input name="bill_city"   autocomplete="billing address-level2">
  <input name="bill_zip"    autocomplete="billing postal-code">
</fieldset>

go deeper

for a junior

Know that autocomplete values can carry a shipping or billing prefix before the field name, and that a checkout with two addresses needs them on every field of both blocks.

for a middle

State the full token order — section-*, then shipping or billing, then a contact qualifier, then the field name — and explain that an out-of-order value is unrecognised and silently falls back to guessing.

for a senior

Diagnose the duplicate-address symptom from a live checkout, and know that section-* is the escape hatch when two groups share a mode. Keep the token grouping separate from the name attributes the server consumes.

for a principal

Treat checkout autofill as a conversion surface: decide where the address component owns its tokens, how multi-address flows are named consistently, and how it is verified so a redesign does not quietly regress the fill.

## The problem this solves A browser's autofill store holds structured profiles: an address, maybe several, plus payment methods. When a form contains one postal-code field, matching it to the profile is easy. When it contains two — shipping and billing — the browser has to decide whether they are the same address entered twice or two distinct ones. Nothing in `<input name="zip2">` answers that question, so the browser guesses, and the familiar symptom is a user's home address dropped into both blocks, or the second block left empty. ## The grammar An autocomplete value is a token sequence, not a single word. The permitted order is: ``` [section-*] [shipping | billing] [home | work | mobile | fax | pager] field-name ``` Everything except the field name is optional, and the order is fixed — a value whose tokens appear in a different order is not a recognised autofill value at all, and you silently fall back to heuristics. - **`shipping` / `billing`** are the *autofill modes*. They apply to address and contact fields and say which address this field belongs to. - **`home` / `work` / `mobile` / `fax` / `pager`** narrow contact details: `shipping mobile tel` is the mobile number for the delivery contact. - **`section-*`** is an arbitrary group name you invent. Anything after the `section-` prefix is yours: `section-gift`, `section-passenger-1`. Fields sharing a section name form one logical group. ## The worked checkout ```html <fieldset> <legend>Shipping address</legend> <input autocomplete="shipping name"> <input autocomplete="shipping street-address"> <input autocomplete="shipping address-level2"> <input autocomplete="shipping postal-code"> <input autocomplete="shipping country"> </fieldset> <fieldset> <legend>Billing address</legend> <input autocomplete="billing name"> <input autocomplete="billing street-address"> <input autocomplete="billing address-level2"> <input autocomplete="billing postal-code"> <input autocomplete="billing country"> </fieldset> ``` With this markup the browser can offer the delivery address in one block and the card's registered address in the other, and filling one does not disturb the other. ## When one mode is not enough Modes come in exactly two flavours, so a form with two addresses of the same kind — a gift order with a recipient and a sender, a booking with several travellers, a form that captures a previous address for a credit check — needs `section-*`: ```html <input autocomplete="section-recipient shipping street-address"> <input autocomplete="section-recipient shipping postal-code"> <input autocomplete="section-sender shipping street-address"> <input autocomplete="section-sender shipping postal-code"> ``` The names carry no meaning to the browser; what matters is that fields in the same section belong together and fields in different sections do not. Keep them stable, since changing them changes the grouping. ## Payment fields The card fields — `cc-name`, `cc-number`, `cc-exp`, `cc-csc` — are their own group and do not take `shipping` or `billing`. They can still take a `section-*` prefix if a page genuinely collects more than one card, which is rare. Note also that the security code is a value browsers deliberately avoid storing, so expect the user to type `cc-csc` even when everything else fills. ## Mistakes that show up in review **Token order reversed.** `shipping section-gift street-address` is not valid. `section-*` comes first. **A mode on a field that has no mode.** `billing username` is not meaningful; modes belong on address and contact fields. **Making up a mode.** `delivery`, `home-address`, `primary` are not autofill modes. The two mode tokens are `shipping` and `billing`; anything else has to be expressed with `section-*`. **Reaching for `off` on the second block.** It suppresses help instead of describing the field, and browsers may ignore it anyway. Describe, do not suppress. **Relying on a "same as shipping" checkbox alone.** The checkbox is good UX and worth having, but it is your script copying values; it does nothing for the case where the two addresses genuinely differ, which is the case that needed the grouping tokens in the first place. **Duplicating `name` values.** Grouping tokens describe the fields to the browser; your server still needs distinct `name` attributes (`shipping_zip`, `billing_zip`) to receive both values. The two mechanisms are independent. ## Why this is worth the effort A long checkout is where conversion is lost, and the address blocks are the longest part. A form the browser can fill in two taps rather than forty keystrokes on a phone converts measurably better, and it produces cleaner data — a browser-supplied address is a structured record from the user's profile, not a hand-typed string with a transposed postcode. The grouping tokens are the difference between autofill helping once and autofill helping for the whole form.

  • A gift-order form has both a recipient address and a sender address, and both are shipping. How do you distinguish them?
    With `section-*`. Give each group an invented name and put it first: `section-recipient shipping street-address` against `section-sender shipping street-address`, repeated across every field of each block. The browser treats fields sharing a section name as one logical address group. The names mean nothing to the browser, so pick something stable and readable — changing them changes the grouping.
  • Does the shipping or billing token change what the server receives on submit?
    No. Autocomplete tokens describe fields to the browser and never touch submission. The server sees the `name` attribute and the value, so you still need distinct names like `shipping_postcode` and `billing_postcode`. Confusing the two mechanisms leads to forms where both blocks submit under one name and one address silently wins.
  • The team's fix for the duplicate-address bug is a "billing same as shipping" checkbox. Is that enough?
    It is a good addition but not a substitute. The checkbox is your own script copying values, and it only helps in the case where the addresses match. The bug you were fixing — the browser filling both blocks with the same stored address when they genuinely differ — is untouched by it. Keep the checkbox for convenience and add the grouping tokens for correctness.

saying these in an interview costs you the question

  • Writes the section prefix after the shipping token
  • Invents modes such as delivery or primary
  • Turns autofill off on the second address block
  • Thinks grouping tokens change what the server receives
  • Believes a same-as-shipping checkbox removes the need for tokens

context