Browse by section

Web Design 日本語

Faster Mobile Forms: inputmode, autocomplete, enterkeyhint

The biggest gains in <input> usability come from writing three attributes correctly: autocomplete, inputmode and enterkeyhint. On mobile in particular, having them or not visibly changes how long a form takes to fill in.

This article sticks to those three attributes only: how to use them and where people trip. To be precise about the framing, none of them was added in 2023. They had been in the specification for years; what happened around then is that they became safe to rely on in every browser. Choosing a type, and validation, are each handled in a separate article.

Sponsored

type, inputmode and pattern do different jobs

They look similar and do completely different things. Confusing them produces bugs like “letters get into a numbers-only field” and “the mobile keyboard never switches.”

Attribute Controls Does not control
type Value interpretation, built-in validation, UI (calendar etc.) —
inputmode Which soft keyboard appears on mobile What can be entered (appearance only)
pattern Format checking at submit time Keyboard switching; blocking keystrokes

The one most often misunderstood is inputmode. It changes which keyboard appears and nothing else—it does not restrict the value. A field marked inputmode="numeric" will happily take letters typed on a desktop keyboard. If the format has to hold, you need pattern and server-side validation.

Matching the mobile keyboard with inputmode

inputmode decides the keyboard shown on a phone. The conclusion: for fields that hold digits, use type="text" with inputmode="numeric" rather than type="number".

Where this bites is fields that are just a run of digits—postal codes and card numbers. Use type="number" there and leading zeros get dropped, while hyphens become impossible to type (the full reasoning is in the HTML input element, type by type).

The right combination is type="text" plus inputmode="numeric" plus pattern.

<!-- do not use type="number" for a postal code -->
<input type="number" name="zip">

<!-- do this -->
<label for="zip">Postal code</label>
<input type="text" id="zip" name="zip"
       inputmode="numeric"
       autocomplete="postal-code"
       enterkeyhint="next"
       pattern="\d{3}-?\d{4}"
       title="Enter as 123-4567 or 1234567"
       maxlength="8">

Phone numbers can use type="tel", but it brings no format validation of its own—formats differ by country. Bring up the keypad with inputmode="tel" and supply the format with pattern.

inputmode values

Value Keyboard Use for
numeric Digits only Postal codes, verification codes, card numbers
decimal Digits plus decimal point Amounts, weights
tel Phone keypad (with * and #) Phone numbers
email Includes @ Email addresses
url Includes / and .com URLs
search Enter becomes “Search” Search fields
none No keyboard When you render your own keypad

Mixing up numeric and decimal shows up as an amount field where the decimal point cannot be typed. When in doubt, decide it on whether a decimal point is needed.

Sponsored

autocomplete is the biggest single win

Nothing else moves the needle as much. It lets browsers and password managers pour saved addresses, names and card details into the form in one tap.

The catch: invented values like autocomplete="on" or autocomplete="fullname" do nothing. You have to use the tokens defined in the specification.

<input type="text"  name="lname" autocomplete="family-name">
<input type="text"  name="fname" autocomplete="given-name">
<input type="email" name="email" autocomplete="email">
<input type="tel"   name="tel"   autocomplete="tel">
<input type="text"  name="zip"   autocomplete="postal-code">
<input type="text"  name="addr1" autocomplete="address-level1"> <!-- state/prefecture -->
<input type="text"  name="addr2" autocomplete="address-level2"> <!-- city -->
<input type="text"  name="addr3" autocomplete="address-line1">  <!-- street -->

For a date of birth, use autocomplete="bday". If you take the whole address in one field rather than splitting it, use street-address; for an unsplit name, name.

Login and sign-up take different autocomplete values

Getting this wrong makes password managers misbehave. The values differ between logging in and signing up.

<!-- login -->
<input type="text"     name="user" autocomplete="username">
<input type="password" name="pass" autocomplete="current-password">

<!-- sign-up and password change -->
<input type="password" name="new"  autocomplete="new-password">

<!-- SMS verification code (auto-filled) -->
<input type="text" name="code"
       inputmode="numeric" autocomplete="one-time-code" maxlength="6">

autocomplete="one-time-code" is what lets iOS and Android fill an SMS verification code automatically. Its presence or absence visibly changes two-factor completion rates.

Put current-password on a sign-up field and the saved password may get filled in instead. Registration and password changes take new-password—worth committing to memory.

Sponsored

enterkeyhint changes the action key

The bottom-right key on a mobile keyboard defaults to “return” or “done”. enterkeyhint turns it into “search”, “send” or “next”.

<input type="search" enterkeyhint="search" placeholder="Search this site">

<input type="text"  enterkeyhint="next"   name="lname">
<input type="text"  enterkeyhint="next"   name="fname">
<input type="email" enterkeyhint="send"   name="email">

The values are enter, done, go, next, previous, search and send. Simply putting next across a multi-field form removes a lot of thumb travel.

To put the roles side by side: inputmode sets which keyboard appears, autocomplete sets what can be poured in, and enterkeyhint sets the label on the action key. They do not conflict, so on any field people will fill in on a phone, write all three.

Summary

  • inputmode only changes the keyboard. It does not restrict the value—hold the format with pattern and on the server
  • Postal codes, phone numbers and card numbers: type="text" + inputmode="numeric" + pattern
  • Do not mix up numeric (digits only) and decimal (decimal point included)
  • Write autocomplete with the tokens from the specification. on and invented values do nothing
  • Do not mix up current-password and new-password
  • Use autocomplete="one-time-code" for SMS verification
  • enterkeyhint turns the action key into “next” or “search”

All three are a single line each and change nothing visually. They still cut the time a form takes on a phone, which makes them the first thing I look at when revisiting an existing form.

The quirks of each type (date, number, file, datalist and the rest) are in the HTML input element, type by type; error display and submission (:user-invalid, setCustomValidity(), requestSubmit()) in HTML form validation and submission without a library. Confirmation dialogs are covered in the HTML dialog element.