The ultimate guide for the perfect <form>

We all know those forms where using the autocompletion ends up in a complete mess. Some fields stay empty, some are filled with incorrect values and others rely on placeholders to tell us what they should be filled with. Is this value correct? Perhaps, but the only way to be sure is to remove the autocompleted value to see the placeholder again. It’s frustrating and it doesn’t have to be like this!

Getting the markup right

A good form starts with the right markup.

1. Turn off autocorrect

Turn off autocorrect when you don’t need it: It’s annoying when the system tries to correct something it can’t know. This includes names of persons, streets, companies and cities. Whenever you write an <input> ask yourself: Is the potential value of the input part of a dictionary? When the answer is “No” turn off the autocorrection.

2. Turn off autocapitalize

Turn off autocapitalize when you don’t need it. This might apply to e-mail fields only, but it’s helpful to avoid that the first character of an email is written capitalized.

3. Use autocomplete

The autocomplete attribute lets you control how the browser should populate a given form field. It’s the key for a correctly working autocompletion. Common values for the attribute are name, email, username, new-password and current-password, but the list of values you can use is almost endless.

4. Use required

The required attribute specifies that an input field has to be filled out before submitting the form. Try to use it instead of a JavaScript validation (when possible). It’s better to let the browser do its job instead of reinventing the wheel with a custom validation. Browsers are doing a lot out of the box: A tooltip appears and the input scrolls into view when a user tries to submit an empty required field.

It’s also recommended to indicate that a value is required by adding a hint for the user near the input or its label. Yes, even when all fields are required.

4. Use type and pattern

Touch devices can show a different, optimized keyboard layout for each form field once you told them to do so. For example: They numeric keyboard of the iPhone 6S has a hit-area that is 521% larger than the default touch keyboard. It’s perfect for inputs that accept numeric values only.

Optimized keyboard layouts can be triggered using the type and pattern attributes. There’s also a new inputmode attribute, but it can’t be used in many browsers, yet.

  • Use pattern=”[0–9]*” or inputmode=”numeric” to trigger the numeric keyboard
  • Use type="email" to trigger the email keyboard
  • Use type="url" to trigger the URL keyboard

5. Use labels

Designers and developers like to omit the <label> as it makes the form cleaner and the code and styling simpler, but it plays an important role for users. A form control that solely relies on a placeholder is unidentifiable once it’s filled. This is especially a problem when the form has been filled using autocompletion: Users can’t tell if an input is filled correctly until they remove the value.

6. Use placeholders

Placeholders are hints for users. They should always show a potential value in the expected format. Placeholders like +49 or https:// are perfect to tell your users that they should start phone numbers with the country calling code and links with a protocol.

7. Use disabled

Use the disabled attribute to deactivate inputs. Not a class. I repeat: Not a class. disabled can be applied to all kind of form controls and tells the browser to keep a user from using an element. Adding an additional class to do the styling is fine, but remember that you can also select the element using input[disabled] in CSS.

Getting the usability right

The correct markup already sets the base for a good usability.autocorrect, autocapitalize and autocomplete make it easy to fill the form, using type and pattern ensures that touch devices show an optimized keyboard layout and a placeholder lets the user know what we should insert. But that’s not enough. There’s still a lot you can do wrong when it comes to the styling and overall structure. Here’re three great resources to improve the UX of your forms:

Design Better Forms

Common mistakes designers make and how to fix them. More 👉

UX Movement

User experience blog that helps you improve your interface by demonstrating how good and bad design practices affect user behavior. More 👉

Baymard Institute

E-commerce UX research — uncovering what designs cause usability issues and how to create “State of the Art” e-commerce experiences. The free articles also contain some great posts related to forms and inputs. More 👉

Getting the styling right

Styling a form is a nightmare. Elements ship with their own styling which variates from system to system and from browser to browser. There’s even a multi-page guide on MDN explaining “Why is it so hard to style form widgets with CSS?”.

Better default styles for common input elements with formbase

I’ve spend so much time styling forms that I decided to build a base of default styles for common input elements: formbase eliminates cross browser bugs, inconsistencies across systems and applies a beautiful default styling to several input elements. Zero dependencies, no JavaScript, just CSS.

An alternative to formbase is Boilerform: A little HTML and CSS boilerplate that has been started by an idea from Chris Coyier (A Boilerform Idea). It turned into a project that tries to take the pain away from working with forms.

Markup examples

I would like to end this post with a few examples showing common input fields and their correct attributes. Go back to this section whenever you’re writing a form to ensure that your markup follows the best practices.


Tip: Always use a single name field instead of splitting single input entities.


Postal code

Note: Some countries use letters in their postal code. Make sure to remove the pattern when the user should be able to enter a postal code of one of those countries.