When building or using HTML forms, we often layer in a variety of additional elements like labels, help text, validation, and JavaScript behaviors. However, many forms don’t seem to account for some of the built-in features that lead to a much better form experience with minimal effort.

If you’ve ever used a form where your browser feels like it’s being a little too helpful, it’s possible that the form could take advantage of some of these built-in features. For example, if a form has a URL field or a product SKU, spell checking and auto-capitalization are more likely to hinder than help. In that context, we’d like want to let the browser know not to apply those for that field.

We have spellcheck, autofocus, autocapitalize, autocomplete, and autocorrect11The autocorrect attribute is non-standard and only supported in Safari. attributes that can be added to input fields to improve the user experience. All of these help tell the browser and extensions how to handle the input field. And there’s no JavaScript required!

The MDN documentation for these attributes is thorough, so we’ll just cover the basics with some examples here.

spellcheck

The spellcheck attribute doesn’t technically require a value, but I personally like to specify an explicit value. We can set it to true or false, but even an empty string would equate to enabling it. The default behavior for spell-checking varies by browser, so it can be helpful to explicitly enable or disable it for each input. Ultimately, however, it’s only a suggestion to the browser and may not be respected.

It’s also worth noting that the spellcheck attribute can be applied to a containing form element to apply to all of its children inputs. This can make it easier to enable or disable it by default and override the value for specific fields without having to specify it on every field. (Figure 1)

<form action="/check" spellcheck="true"> <!-- Inherit from containing `form` --> <input type="text"> <!-- Explicitly enabled without value --> <input type="text" spellcheck> <!-- Explicitly enabled with `true` --> <input type="text" spellcheck="true"> <!-- Explicitly disabled with `false` --> <input type="text" spellcheck="false"></form>
Figure 1

The spellcheck attribute can provide hints to the user agent about whether or not to perform spell-checking on a given field. It can also be specified on a containing form element so that the value will be inherited by the children inputs.

↩︎

autofocus

The autofocus attribute can be tricky because only one element can have it at a time. Moreover, since screen readers will jump to the auto-focused element, it can be disorienting if the user isn’t expecting it. It’s best to use sparingly—especially if the element is far enough into the page that it’s likely to cause scrolling. (Figure 2)

<form action="/focus"> <input type="text" autofocus></form>
Figure 2

The autofocus attribute is boolean, so there’s no value to specify.

↩︎

autocapitalize

The autocapitalize attribute provides a few different options for letting the browser know how to handle it. Like spellcheck, it can also be specified on a containing form element to apply to all of its children inputs.22URL, email, and password inputs will never autocapitalize. Also like spellcheck, the default behavior varies by browser, so it can be helpful to explicitly enable or disable it for each input. (Figure 3)

There are four possible behaviors for autocapitalize:

  • none or off - Disable it, and don’t capitalize anything. (Default for Firefox)
  • sentences or on - Only capitalize the first letter of each sentence. (Default for Chrome & Safari)
  • characters - Capitalize every single character.
  • words - Only capitalize the first character of each word.
<form action="/capitalize" autocapitalize="true"> <!-- Inherit from containing `form` --> <input type="text"> <!-- Explicitly enabled --> <input type="text" autocapitalize="on"> <input type="text" autocapitalize="sentences"> <!-- Explicitly disabled --> <input type="text" autocapitalize="off"> <input type="text" autocapitalize="none"> <!-- Capitalize every single character --> <input type="text" autocapitalize="characters"> <!-- Capitalize first character of each word --> <input type="text" autocapitalize="words"></form>
Figure 3

Caption

↩︎

autocomplete

The autocomplete attribute is a bit more advanced than the others and supports a wider range of values based on the type of content expected in the field.33Make sure to look over the WHATWG standards for more detailed explanations of how it all works. It can be specified on a containing form element to apply to all of its children inputs, but it can also be specified on individual inputs to override the form-level value.

The simplest options for autocomplete are on or off, but when we use on, we’re effectively letting the browser decide how to handle it. In addition to these values, we can choose from a list of specific values to provide hints to the browser about the expected type of content. These include parts of names like given-name, family-name, nickname, and many, many more. I encourage you to check out the full list to see if there are any that might be useful for your forms. (Figure 4)

<form action="/autocomplete"> <!-- We have endless variations for parts of names, but full name is easy. --> <input name="full-name" autocomplete="name"> <!-- We can specify one-time codes/passwords to be autocompleted. --> <input type="password" name="one-time-code" autocomplete="one-time-code"> <!-- We can specify when passwords fields are for the current value or a new one. --> <input type="password" name="new-password" autocomplete="new-password"> <input type="password" name="current-password" autocomplete="current-password"></form>
Figure 4

We can use autocomplete to provide hints to the browser from a list of over 50 values representing various common types of input.

↩︎

In addition to the specific value types, we can use section- prefixes to group fields. The most common example would be a form that includes both billing and shipping addresses. In fact, the autocomplete attribute explicitly supports the values of billing and shipping to differentiate between the two. (Figure 5) Another example might be a form where someone has to specify their information and that of a guest. In that context, the form would likely have multiple name fields and a section-guest value can help provide a level of hinting to the browser.

<form action="/autocomplete" capitalize="true"> <fieldset> <legend>Billing Address</legend> <label for="billing-address-one">Address Line 1</label> <input id="billing-address-one" name="billing-address-one" autocomplete="section-billing billing address-line1"> <label for="billing-address-two">Address Line 2</label> <input id="billing-address-two" name="billing-address-two" autocomplete="section-billing billing address-line2"> <!-- ... --> </fieldset> <fieldset> <legend>Shipping Address</legend> <label for="shipping-address-one">Address Line 1</label> <input id="shipping-address-one" name="shipping-address-one" autocomplete="section-shipping shipping address-line1"> <label for="shipping-address-two">Address Line 2</label> <input id="shipping-address-two" name="shipping-address-two" autocomplete="section-shipping shipping address-line2"> <!-- ... --> </fieldset></form>
Figure 5

In addition to the core values, we can use section- prefixes to group related fields, and in the case of addresses, we even get explicit support for billing and shipping addresses.

↩︎

autocorrect

Last, and kind of also least, we have autocorrect—or rather those of using Safari have it. It can be set to on or off, and even though it’s a non-standard attribute, it’s easy enough to add and will help anyone using Safari. (Figure 6)

<!-- Since product SKU's don't use dictionary words, don't use autocorrect --> <input type="text" name="sku-code" autocorrect="off"> <!-- Long-form prose can potentially benefit from autocorrect --> <textarea name="summary" autocorrect="on"></textarea>
Figure 6

The autocorrect attribute is only supported by Safari, but it can still be helpful to explicitly enable or disable it depending on the field.

↩︎

Conclusion

While they feel like small details, when we set these attributes on inputs, we streamline things for visitors while also guiding the browser on when it should just get out of the way. Ultimately, since the effort is relatively low for each of these attributes, it’s definitely something worth considering next time you’re working on forms.