The full list of inputmode
values that you can use are listed below with their keyboard appearance on iOS. Android will display different variations.
none
: stops virtual keyoards appearing for when you want to implement your own keyboard (you probably don't want this)text
: the defaultnumeric
: just numbersdecimal
: numbers and a decimal pointtel
: numbers and other dial pad charactersurl
: the normal keyboard, with a period, forward slash and ".com" in place of the space baremail
: the normal keyboard, with a small space bar, an "@" symbol and a periodsearch
: the normal keyboard, with a slightly smaller space bar, a period and a highlighted button that says "go" rather than the normal "return"inputmode
is also supported on <textarea>
s and any element in contenteditable
mode.
Get the right keyboard and your users will thank you as they input their data.
If you need to display an <input>
element, but you don't want a user to be able to change the contents or you intend to change the contents in some other programmatic way, you might think that enabling the disabled
attribute will help. However, disabled input elements are removed from the accessibility tree and thus disappear for users of assistive technologies. The contents of disabled inputs are also not submitted with the form.
An alternative to disabled
is the readonly
attribute. It makes the field inert, but the content remains accessible and will be submitted with the rest of the inputs within the form.
<label for="input">The label</label>
<input type="text" value="You can't change this" readonly id="input" />
Note by Manuel: Not all screen readers announce the field as “read only”. You may want to test it first and decide whether to support it with an additional description.
You can also target readonly
elements in CSS with the pseudoclass :read-only
. Elements that can be read and written can be targeted with the :read-write
pseudoclass.
readonly
only works on <input>
s that behave like text controls and is also supported on <textarea>
elements.
Choosing whether to use readonly
over disabled
on an element is about choosing whether an element is usable on the page. Don't forget to consider this.
You might think the only way to have a user access the camera on their mobile device and take pictures or video is via JavaScript and the getUserMedia
API. But camera access is also available declaratively. On a file upload <input>
you can specify the capture
attribute, which will direct the element to trigger the device camera.
Sadly this is a feature that is limited to the mobile versions of supporting browsers, on a desktop it will work like a regular file upload field.
For devices with front and back cameras, you can even provide hints for which camera to use. So if you are asking your user to take a selfie, you can set capture="user"
to prefer the front-facing camera. If you are more interested in pictures of the surroundings, you can set capture="environment"
to hint that you'd prefer the rear facing camera. The device can override these hints if, for example, it doesn't have a user facing camera available.
You can also use the accept
attribute to hint at the type of content you want from the camera. If you accept image types, then the camera will be primed to take pictures, but if you hint that you want video then the camera will set up to record instead.
So, using the following HTML will produce the result below.
<label for="input">Cheeeeese</label>
<input type="file" capture="user" accept="image/jpeg,image/png" id="input" />
This is a great way to capture an avatar for a user with no need for JavaScript, just HTML.
The spellcheck
attribute is a generic attribute that can be used on any element. It's used to trigger the browser's spellchecking capability on elements where you also set contenteditable="true"
. It also works on <input>
elements and is definitely something you should consider.
Different browsers treat <input>
elements differently. Firefox and Safari on the desktop will not spellcheck <input>
elements without the attribute, but Chrome and Safari on iOS will. To get consistent behaviour across browsers, you should set the spellcheck
attribute to "true" or "false" depending on the contents of the <input>
.
For regular text, help your users out with spellcheck="true"
. For identifiers, like usernames, email addresses, URLs, or other things that you would not expect to find in a dictionary, set spellcheck="false"
.
One other thing to consider, how spellchecking is implemented is left to the browser. Chrome and Edge have been known to send the contents of <input>
elements to a spellchecking service over the network, exposing whatever was in the field. If your <input>
elements are capturing sensitive data, like personally identifiable information, like names or birth dates, or passwords, then you should set spellcheck="false"
to avoid sharing it.
<label for="input">Name</label>
<input type="text" spellcheck="false" id="input" />
Note that a <input>
with type
of "password" won't leak its value, but if you implement a show password feature that sets the type to "text" then this opens the field to be spellchecked.
Getting your spellcheck settings consistent helps your users as they input data into your forms and being aware of the risks of spellcheck helps you protect your users' data.
The default behaviour for an <input>
on a mobile device is to capitalise the first word and make all other characters lowercase. This is fine when writing a sentence, however things like names and addresses expect all words to be capitalised. Other inputs, like airline ticket identifiers and UK postcodes expect their input to be in all capitals.
The autocapitalize
attribute is your friend in this case and saves your users having to use the shift key to produce text in the format you want it.
Capitalise the first letter of every word with autocapitalize="words"
and capitalise every letter with autocapitalize="characters"
.
<label for="input">Name</label>
<input type="text" name="full-name" autocapitalize="words" id="input" />
One thing to note, the autocapitalize
attribute does not have an effect where it doesn't make sense, like on <input>
elements with type
of "email", "url", and, most importantly, "password".
Getting autocapitalisation right will make entering data on mobile devices much easier for your users.
Last but not least, my absolute favourite <input>
attribute is the autocomplete
attribute.
It provides hints for the browser to fill in input fields with data it already knows. The autocomplete
attribute can take an enormous number of values that associate an <input>
with many things the browser knows or can find out.
For things like registration or logging in, you can set autocomplete
to values like "username" or "email". For passwords, you can use the value "new-password" to prevent a browser from autocompleting an existing password and to suggest a secure new password. Or you can use the value "current-password" to indicate that the browser or password manager should autocomplete the field with the user's password.
You can autocomplete a user's address with values like "street-address", "country-name" and "postal-code". For ecommerce applications you can combine the values with additional identifiers to separate between "billing" and "shipping" addresses.
<label for="input">Address</label>
<input type="text" autocomplete="street-address shipping" name="street-address" id="input" />
For one time passwords sent over SMS, you can use the value "one-time-password" to indicate that the browser should look at recently received messages and extract the OTP for autocomplete.
And if you're implementing passkeys, you can use the autocomplete
value "webauthn" to help implement passkey autofill.
Correctly using the autocomplete
attribute is even a sufficient technique to fulfill the WCAG level AA rule "identify input purpose". Providing fine-grained hints to the browser for the type of content the input fields are expecting means that they can be filled in saving time and typing for all users.
Conversely, there are times you might want to disable autocomplete entirely. Using autocomplete="off"
will stop the browser remembering what was entered in an input. This is useful for fields that expect different input each time, like a text CAPTCHA.
Getting the right autocomplete attributes helps all users fill in inputs with the least amount of effort.
Designing and developing forms that work for all users is hard. The <input>
element has many options that you can choose to use to make your forms more usable and accessible.
For controlling the available virtual keyboards use inputmode
. To control whether an <input>
can be updated, but also still read and submitted, choose readonly
over disabled
. You can trigger the camera on mobile devices using capture
. Use the spellcheck
attribtue to control whether spellchecking is activated on an input, and remember to set it to "false" on sensitive inputs. Save users time by using autocapitalize
to control the capitalisation of text in an input. And finally, use autocomplete
to help the browser fill in the contents of an input and save your users typing.
All of these attributes, when deployed correctly will help your users fill in your forms with the least amount of effort.
Phil Nash is a developer advocate for Sonar living in Melbourne, Australia. He loves working with HTML, CSS, and JavaScript, in that order, to build web applications and tools to help developers.
Blog: philna.sh
Mastodon: Mastodon
Twitter: Twitter
Bluesky: Bluesky
LinkedIn: LinkedIn