---
title: "Autocomplete and input types"
description: "The attributes that decide which keyboard appears and whether the browser can fill a field, including the health fields for which no autofill token exists."
url: "https://opsinjs.pensievelabs.org/patterns/forms/autocomplete-and-input-types"
source: "https://opsinjs.pensievelabs.org/patterns/forms/autocomplete-and-input-types.md"
section: "Patterns"
kind: "pattern"
reviewed: "2026-09-20"
reviewer: "engineering"
aliases: ["autocomplete attribute", "inputmode", "input type number", "keyboard type", "autofill"]
implements: ["field", "reading-input", "log-sheet"]
---

> Elements written as `<PascalCase … />` below are opsinjs documentation
> components. Their attributes are the content: the values they render are
> generated from `tokens/*.json` and `registry/catalogue.ts` and are
> published separately at https://opsinjs.pensievelabs.org/r/index.json and under the Reference
> section.
> Nothing is missing from this page. The data simply does not live in
> the prose.

<PageTemplate kind="pattern" />

## When to use [#when-to-use]

Every text or numeric field, every time. These attributes cost one line each and
they decide three things the reader notices immediately: which keyboard appears,
whether the browser or password manager can fill the field, and whether the
value survives being typed on a phone.

They are also a conformance requirement. WCAG 2.2 SC 1.3.5 (Identify Input
Purpose) requires that fields collecting information **about the user** carry
the corresponding autofill token, where one exists in the HTML specification's
list of autofill field names.

## When not to use [#when-not-to-use]

* **The value is not about the reader.** A search box, a note, a free-text
  symptom description: no autofill token applies, and inventing one is worse
  than omitting it. `autocomplete="off"` is the honest answer.
* **The field is a one-time code.** Use `autocomplete="one-time-code"`, not a
  numeric-only trick, and make sure paste works. WCAG 2.2 SC 3.3.8 (Accessible
  Authentication) exists partly because segmented code inputs commonly break it.
* **You want the wiring.** Controlled inputs, masks and parsing are
  [Handbook → Forms](../../handbook/forms.mdx).

## How it works [#how-it-works]

Four attributes, in the order they matter.

<FlowDiagram>
  {`flowchart TD
    A["A field"] --> B{"Is it about the reader?"}
    B -->|"yes"| C{"Is there a spec autofill token?"}
    C -->|"yes"| D["Set autocomplete to that token"]
    C -->|"no"| E["autocomplete off, and do not invent a token"]
    B -->|"no"| E
    D --> F{"Is the answer numeric?"}
    E --> F
    F -->|"yes"| G["type text plus inputmode decimal or numeric"]
    F -->|"no"| H["The semantic type: email, tel, url, date"]
    G --> I["enterkeyhint, autocapitalize, spellcheck as appropriate"]
    H --> I`}
</FlowDiagram>

### `autocomplete` [#autocomplete]

Use the tokens from the HTML specification's autofill field names. That is the
same list WCAG 2.2 SC 1.3.5 points at. The ones a consumer health product
actually needs:

| Field                           | Token                                                             |
| ------------------------------- | ----------------------------------------------------------------- |
| Full name                       | `name`                                                            |
| First and last name separately  | `given-name`, `family-name`                                       |
| Date of birth, one field        | `bday`                                                            |
| Date of birth, three fields     | `bday-day`, `bday-month`, `bday-year`                             |
| Email                           | `email`                                                           |
| Phone                           | `tel`                                                             |
| Address                         | `street-address`, `address-level2`, `postal-code`, `country-name` |
| Sex, as an administrative field | `sex`                                                             |
| One-time code                   | `one-time-code`                                                   |
| Password                        | `current-password`, `new-password`                                |

**There is no autofill token for a health reading.** No `height`, no `weight`,
no `blood-pressure`, no `medication`. This is correct and you should not
approximate it: setting `autocomplete="on"` on a weight field invites the
browser to offer an unrelated stored value, and setting a made-up token does
nothing at all. Use `autocomplete="off"` and rely on your own prefill from the
reader's previous entry. See [Daily logging](../daily-logging.mdx).

### `inputmode` and `type` [#inputmode-and-type]

For any number a reader types, prefer `type="text"` with `inputmode="decimal"`
over `type="number"`. `type="number"` looks like the obvious answer and brings
several problems that are specifically bad for health values:

* The scroll wheel and arrow keys change the value when the field has focus, so
  a reader scrolling the page can silently alter a reading.
* Leading zeros and trailing decimal points are handled inconsistently.
* Locale decimal separators, such as a comma in much of Europe, are handled
  inconsistently, and the field may report an empty value for something the
  reader can see they typed.
* Spinner buttons are small targets that do not meet the 44pt floor and invite
  thirty taps to reach 138.

`inputmode="decimal"` gets the numeric keypad without any of that.

Use `inputmode="numeric"` for integers with no decimal part, `type="tel"` for
telephone numbers (never for other digits), and `type="email"` for email.

### The rest [#the-rest]

* `enterkeyhint="next"` or `"done"` so the return key does what the reader
  expects at the end of a sequence.
* `autocapitalize="none"` and `spellcheck="false"` on codes, identifiers and
  units. A red squiggle under a medication name the reader spelled correctly is
  a small, repeated insult.
* `autocorrect="off"` on medication names, which autocorrect mangles reliably.
  See [Medications](../ask-users-for/medications.mdx).

## Content [#content]

<DoDont>
  <DoDont.Do>
    A weight field: `type="text" inputmode="decimal" autocomplete="off"`, with
    the unit displayed beside the field rather than typed into it.
  </DoDont.Do>

  <DoDont.Dont>
    `type="number"` with a spinner, no `inputmode`, and the unit expected inside
    the value as "72 kg".
  </DoDont.Dont>
</DoDont>

<DoDont>
  <DoDont.Do>
    Three date-of-birth fields with `bday-day`, `bday-month`, `bday-year`, each
    with `inputmode="numeric"` and a visible label.
  </DoDont.Do>

  <DoDont.Dont>
    A single `type="date"` picker with no keyboard entry path, which is
    unusable for a birth year forty years in the past. See
    [Date of birth](../ask-users-for/date-of-birth.mdx).
  </DoDont.Dont>
</DoDont>

## Accessibility [#accessibility]

* **WCAG 2.2 SC 1.3.5** is met by using the specification's tokens, not by
  approximating them. A wrong token is a failure; a missing token on a field
  that has no applicable purpose is not.
* **`inputmode` is not a label.** It changes the keyboard and nothing else; the
  field still needs a visible label and, where the format is not obvious, a
  hint.
* **Never disable paste.** It breaks password managers, breaks one-time codes
  and disproportionately affects readers using assistive technology or
  switch access. It is also implicated in WCAG 2.2 SC 3.3.8.
* **Do not auto-advance between segmented inputs.** Moving focus when a segment
  fills is disorienting with a screen reader and makes correction difficult; see
  [Question pages](./question-pages.mdx).
* **Spinner controls, where they exist at all, meet the target-size floor** in
  [Density and touch targets](../../foundations/space/density-and-touch.mdx),
  and typing is always available as an alternative.
* **`autocomplete="off"` does not defeat a password manager** and should not be
  used to try. Use it only where no purpose applies.

## Research [#research]

<ResearchNote evidence="cited" date="2026-09-02">
  The autofill token list and the requirement to use it are specified rather
  than argued: WCAG 2.2 SC 1.3.5 (Identify Input Purpose) references the HTML
  specification's autofill field names, and both are public, checkable documents.
  The absence of any token for height, weight, medication or a reading is a fact
  about that list, and it is the most useful thing on this page.

  The preference for `type="text"` with `inputmode="decimal"` over
  `type="number"` is a widely shared engineering recommendation based on the
  behaviours listed above, each of which is reproducible in a browser today. We
  cite no study for it because none is needed. The failure modes are
  observable.
</ResearchNote>

## Updates to this page [#updates-to-this-page]

<Reviewed />
