UX Design and Development course

Making Forms Fabulous with HTML5



Filling out forms on the web has never been exactly fun, and it can be downright painful on a mobile device with its on-screen keyboard. But modern browsers help to make this much easier by providing new semantic input types and validation.

Browser support

Currently support for the new form and input elements is widespread on modern browsers, though there is often some difference in the way some pickers are displayed on desktop. Mobile browsers are relatively consistent in showing the right keyboard depending on the input type selected. For the most up to date information, check out the state of HTML5 Form Features on CanIUse.com.

New input types

HTML5 introduces a number of new input types. These new input types give hints to the browser about what type of keyboard layout to display for on-screen keyboards.


Many browsers provide built-in validation for some input types like email and url. On other elements, you can indicate a valid input format by providing a regular expression in the the pattern attribute. For more information, be sure to read the section on Validation.



Data validation doesn’t just help to keep your data clean, but it also helps improve the user experience. For example, datalists can provide auto-complete in text boxes suggesting options to the user. Warnings can be displayed when the users response doesn’t match the expected format. The JavaScript validation APIs can provide custom validation logic and prompt users with easy to understand error messages when they’ve provided invalid data.

The pattern attribute

The pattern attribute specifies a regular expression used to validate an input field. For the purpose of the example, let's say a part number consists of three uppercase letters followed by four digits. The use of pattern ensure that the field value matches the correct format for a part number.

<input type="text" id="partNumber" pattern="[A-Z]{3}[0-9]{4}" />

The required attribute

If the required attribute is present, then the field must contain a value before the form can be submitted. For example, to make the part number in the previous example required, we’d simply add the required attribute.

<input type="text" required id="partNumber" pattern="[A-Z]{3}[0-9]{4}" />

The min, max and step attributes

For numeric input types like number or range, you can specify the minimum and maximum values, as well as how much they should each increment/decrement when adjusted by the slider or spinners.

<input type="number" id="qty" min="0" max="100" step="1" />

The maxlength attribute

The maxlength attribute can be used to specify the maximum length of an input or textbox and is useful when you want to limit the length of information that the user can provide. For example, if you want to limit a filename to 12 characters, you can use the following.

<input type="text" id="83filename" maxlength="12" />

The novalidate attribute

In some cases, you may want to allow the user to submit the form even if it contains invalid input. To do this, add the novalidate attribute to the form element. In this case, all pseudo classes and JavaScript APIs will still allow you to check if the form validates.

<form role="form" novalidate>
  <label for="inpEmail">Email address</label>
  <input type="email" id="inpEmail" placeholder="Enter email">

The datalist element

The datalist element isn't an input type, but a list of suggested input values to associated with a form field. It lets the browser suggest autocomplete options as the user types. Unlike select elements where users must scan long lists to find the value they’re looking for, and limiting them only to those lists, datalists provide hints as the user types.

<label for="inpChocType">Chocolates</label>
<input type="text" id="inpChocType" list="chocType">
<datalist id="chocType">
  <option value="white" />
  <option value="milk" />
  <option value="dark" />

Other new form attributes

Several other common form features are provided by new attributes that would have previously required additional code.

The autocomplete attribute

There may be cases where you don’t want the browser to automatically fill in data based on users past entries. You may want to use this in fields like one-time passwords, pin numbers or password hints. In this case, you can add the autocomplete="off" to either the form element or an individual element.

<input type="number" id="pinNum" min="0" max="9999" autocomplete="off" />

The autofocus attribute

On some forms, like the Google home page for example, you want the focus to immediately jump to a specific input so that the user can quickly begin using the form. While there are JavaScript helpers to do this, they can sometimes be annoying when they move focus after you’ve already started typing. Instead, you can use the autofocus attribute on an input element to specify that element as the primary form element.

<input type="text" id="partNum" pattern="[A-Z]{3}[0-9]{4}" autofocus />

The placeholder attribute

The placeholder attribute provides a hint to the user about what’s expected in the input by displaying its value as light text until the element gets focus. The browser automatically handles blank values, dirty inputs and other input states that would previously have to be special cased in JavaScript.

<input type="text" id="partNum" pattern="[A-Z]{3}[0-9]{4}" placeholder="XXX9999"/>

Styling with CSS3

HTML5 also introduces a number of new pseudo-classes that can be used to style inputs based on their value or attributes, making it easier for users to understand if they’ve filled the form out properly before trying to submit it.

  • :valid and :invalid - explicitly sets the style for an element when the input is valid/invalid.
  • :required and :optional - sets the style for elements that are required or optional.
  • :in-range and :out-of-range - styling for elements that support the min and max attribute

The example below sets the outline of the box to be red when the user has provided invalid input, and to attract their attention, makes the text bold when the field has focus.

input:invalid {
  outline: 2px solid red;
input:focus:invalid {
  color: red;

Validation happens immediately as the user types, and it’s possible they’ll see the invalid style while typing. To prevent this, you can set the style to something else, like the example below.

input:not(:focus):invalid {
  outline: 2px solid red;
input:focus:invalid {
  outline: 2px solid blue;

Unfortunately this does mean that they won’t know the data entered is invalid until they move the focus away from that input.