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
inputmodeonly changes the keyboard. It does not restrict the value—hold the format withpatternand on the server- Postal codes, phone numbers and card numbers:
type="text"+inputmode="numeric"+pattern - Do not mix up
numeric(digits only) anddecimal(decimal point included) - Write
autocompletewith the tokens from the specification.onand invented values do nothing - Do not mix up
current-passwordandnew-password - Use
autocomplete="one-time-code"for SMS verification enterkeyhintturns 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.