Can you imagine what the web would be like if it were truly read-only? What if there were no way for a user to interact with a site by providing personal data? With no way to input data, the Internet would be full of "brochure-ware" sites that could not engage in any real business exchanges. The value of the Internet would be insignificant compared with what it is today.

So it goes without saying that a required factor for many successful websites is the ability to acquire data from a user. And because user interaction plays such a key role in the overall web experience, it isn't surprising that among the many improvements found in HTML5 are feature enhancements to form input. In this article, I will introduce these new form features, exploring some of the new elements and attributes, how to apply styles, and new ways to control validation in script. Rather than try to cover everything that is new, instead I will focus on some practical aspects of HTML5 form development that you can start using today.

Examining a Simple HTML Form

To provide some context for the new features, let's first peer into a simple HTML form that doesn't use any of the new features, as shown in Figure 1.

Figure 1: Simple HTML form
<form> <!-- action & method attributes supplied by developer -->
    <label for="name">Name</label>
    <input id="name" name="name" type="text" />
    <label for="email">Email</label>
    <input id="email" name="email" type="text" />
    <label for="site">Site</label>
    <input id="site" name="site" type="text" />
    <label for="phone">Phone</label>
    <input id="phone" name="phone" type="text" />
    <input id="submit" name="submit" type="submit"
     value="Send Data" />
</form>

With some Cascading Style Sheets (CSS) styles applied, the rendering of the simple form, shown in Figure 2, is a grouping of text boxes with a submit button.

Figure 2: Simple HTML form, rendered in a browser

The simple form is functional, but it poses some common data-collection challenges. For example, consider the same form containing data entered by a user, as shown in Figure 3. When the user clicks the Send Data button, will the data entered be valid according to the requirements of the web developer? In the simple HTML form, the data will be submitted as is.

Figure 3: Data entered into simple HTML form

As web developers, when we observe how users might use (or abuse) our forms, we should contemplate the following questions when developing an application:

  • Are all fields required?
  • Does the user understand what data is being requested?
  • Will the data entered by the user adhere to format requirements?
  • If the user does not complete the form accurately, what should happen?

A consideration of these typical scenarios will help us to appreciate the addition of the new HTML5 form input features. In the remainder of this article, I will discuss the advantages of "what's new" while walking through the process of upgrading the simple HTML form one feature at a time.

New Form Elements and Attributes

HTML5 supports most of the existing form inputs and elements, as well as new features to support data entry in the modern world. Figure 4 lists the input types supported in HTML5.

Type Value Data Type Control Type
Figure 4: Input-type values in HTML5
Hidden an arbitrary string n/a
Text text with no line breaks text field
Search text with no line breaks search field
Tel text with no line breaks text field
url an absolute Internationalized Resource Identifier (IRI) text field
Email an email address or list of email addresses text field
Password text with no line breaks (sensitive information) text field that obscures data entry
Datetime a date and time (year, month, day, hour, minute, second, fraction of a second) with the time zone set to UTC a date and time control
Date a date (year, month, day) with no time zone a date control
Month a date consisting of a year and a month with no time zone a month control
Week a date consisting of a week-year number and a week number with no time zone a week control
Time a time (hour, minute, seconds, fractional seconds) with no time zone a time control
datetime-local a date and time (year, month, day, hour, minute, second, fraction of a second) with no time zone a date and time control
Number a numeric value a text field or spinner control
Range a numeric value, with the extra semantic that the exact value is not important a slider control or similar control
Color an sRGB color with 8-bit red, green, and blue components a color well
Checkbox a set of zero or more values from a predefined list a checkbox
Radio an enumerated value a radio button
File zero or more files, each with a MIME type and optionally a filename a label and a button
Submit an enumerated value, with the extra semantic that it must be the last value selected and initiate form submission a button
Image a coordinate, relative to a particular image's size, with the extra semantic that it must be the last value selected and initiate form submission a clickable image or a button
Reset n/a a button
button n/a a button

Looking over the data being requested in the simple HTML form, we can see an obvious opportunity to explore three new input types: email, url, and tel. What would be the advantage of using these new input types instead of text? The first advantage is semantics. Applying a more specific type than text to form data gives parsing engines a better understanding of what the data means. The other advantages all lie in the power of the browser, which raises a valid concern: What browsers support these new features?

To answer the "browser support" question, I will first acknowledge what browsers I used to support the examples in this article: Internet Explorer (IE) 10.0 (Platform Preview) and Google Chrome (14.0). Although other modern browsers also support many of the new form features, I wanted to keep the focus primarily on the "what and how," not on the "where." As browsers (and standards) continue to evolve, we will have plenty of opportunities to learn about varying implementations.

What about browsers that do not support the new HTML5 form input features? Depending on what new feature is being introduced, there is a different impact and possible way to manage. For example, consider the following type-attribute changes to these input elements in the simple HTML form:

<input id="email" name="email" type="email" />
<input id="site" name="site" type="url" />
<input id="phone" name="phone" type="tel" />

What will happen when a browser that does not support the new type values renders these inputs? The browser will render these the same as type="text". In other words, the form will behave just as it did prior to the changes.

Yet what will happen if the browser supports the new features? Using the same data input, notice how the browser responds to the click of the Send Data button in Figure 5.

Figure 5: Invalid email format on submit

As you might suspect, the input asking for a site URL will give a similar validation message if the data isn't entered properly (i.e., the URL must begin with http://). The input requiring a phone number, however, still behaves like a free-text input. Because there are so many ways to represent a phone number across the world, the initial benefit to indicating an input with a type="tel" is the metadata it provides the parsing engine. However, with the new pattern attribute, we can enforce a custom telephone format using a regular expression, as follows:

<input id="phone" name="phone" type="tel"
 pattern="\(\d\d\d\) \d\d\d\-\d\d\d\d" />

The preceding pattern would require the data to be entered as:

(444) 444-4444

Wouldn't it be nice to inform the user what the valid format for any of the text-based inputs is? That is the role of the placeholder attribute. It acts as a watermark for the input, giving the user direction as to how to enter the data. We will update the three new input types so that they all have placeholders:

<input id="email" name="email" type="email"
 placeholder="name@domain.com"/>
<input id="site" name="site" type="url"
 placeholder="http://www.yoursite.com" />
<input id="phone" name="phone" type="tel"
 placeholder="(###) ###-####" pattern="\(\d\d\d\) \d\d\d\-\d\d\d\d" />

Figure 6 shows what the rendered form looks like after we've added the placeholder attribute.

Figure 6: Inputs displaying placeholder data

Now what about the input requesting the user's name? It is still set to accept any text. However, if the user submits the form with no text, the name will be submitted with no value. What if we require the user to provide a name? This is the purpose of the required attribute. HTML5 allows it to exist in the input element without a value, as follows:

<input id="name" name="name" type="text" required />

However, many developers probably feel uncomfortable seeing an attribute without a value. Therefore, this is also acceptable:

<input id="name" name="name" type="text" required="required" />

And because this is the first input in the form, we can enhance the user experience by giving it immediate focus with the new autofocus attribute. Unlike the required attribute, autofocus should be given a value of true or false, as in the following updated name input:

<input id="name" name="name" type="text" required="required"
 autofocus="true" />

Now when the user pulls up the form and submits it without any data entry, the resulting impact on the displayed form is what is shown in Figure 7.

Figure 7: "Input required" validation message

Adding Style to New Inputs

With new forms of validation come new states for our data. We can style our form to respond to different validation states in CSS. These are the states of data that CSS recognizes:

  • :valid
  • :invalid
  • :required
  • :optional

Microsoft has introduced another state supported in IE 10.0, known as "placeholder" state, which allows CSS developers to control the style of placeholder data. Note that this is not the same as "optional" state, as a required field can have "placeholder" data in it. The syntax for styling placeholder data is as follows:

:-ms-input-placeholder

When states are mixed with the :focus or :not(focus) qualifiers, multiple dimensions of styles emerge. To demonstrate, look at the CSS markup in Figure 8.

Figure 8: CSS definitions for new HTML5 form inputs
input.data:required
{
    background-color:       rgba(255, 255, 0, 0.04);
}
input.data:not(:focus):valid
{

    color:                  rgba(102, 172, 0, 1);
}
input.data:not(:focus):invalid
{
    color:                  rgba(255, 0, 0, 1);
}
input.data:focus
{
    border:                 5px solid #ff5400;
    background-color:       rgba(255, 255, 255, 1);
}
/* IE10 only */
input.data:-ms-input-placeholder:valid,  
input.data:-ms-input-placeholder:invalid
{
    font-style:             italic;  
    color:                  rgba(0, 0, 0, 0.4)        
}

Required data will have a faint yellow background, valid data will be green, and invalid data will be red. When the styles are applied to the page, the result is seen as in Figure 9.

Figure 9: CSS styles applied

Controlling Behavior from Script

With the new form input types, the manner in which each browser handles validation rules can vary slightly. For example, in Figure 7 notice that the message displayed by the browser (Chrome) is Please fill out this field. In IE 10.0, the message is This is a required field. What if we want a consistent message across all browsers, or simply want control over the messaging itself?

To assist with more complex scenarios, modern browsers that support these new input types also allow access to new behaviors in script. With regard to the new input types, take a look at the new methods and attributes of the form element that can be queried from code, as shown in Figure 10.

Name Type Description
Figure 10: JavaScript methods and attributes for HTML5 input validation
validationMessage Attribute Returns the error message that is displayed based on the current state of the form.
validity Attribute Returns a "ValidityState" object for the element. The object contains useful read-only, Boolean attributes to provide what specifically was invalid or not. For example, the valueMissing attribute will return true if the input was required.
willValidate Attribute Returns true if an element can be validated.
checkValidity Method Returns true if the form element is valid, otherwise false. If the element is not valid, an invalid event is fired.
setCustomValidity Method Sets a custom error message for the form element. Setting this message causes the form element to be in an invalid state. To clear error, set with empty string.

Although the table in Figure 10 isn't a complete list of all the new HTML5 input-validation methods and attributes, it represents the core validation behavior that you need to have greater control over the process.

Returning to the issue of how browsers provide error messages, what if we wanted to create our own messages? For example, what if we wanted the browser to display Your full name is required! instead of the browser's default input-validation message? The code in Figure 11 provides a solution.

Figure 11: JavaScript functions for custom validation
(function() {
    // helper functions
    function id(elementId) {
        return document.getElementById(elementId);
    }
    function addEvent(src, eventName, func) {
        src.addEventListener(eventName, func, false);
    }
    // custom validation
    function validate(evt) {
        // reset any existing messages
        this.setCustomValidity("");
        if (!this.validity.valid) {
        // if custom message exists, use it
           if (this.errMessage) {
             this.setCustomValidity(this.errMessage);
           }
        }
    }
    // initialize validation for input
    function initValidate(src, errMessage) {
        // if errMessage provided, set to input
        if (errMessage) { src.errMessage = errMessage; }
        addEvent(src, "change", validate);
        addEvent(src, "invalid", validate);
    }
    // initialize javascipt module
    function initialize() {
        initValidate(id("name"), "Your full name is required!");
    }
    // wire up to loading of document
    if(document.addEventListener) {
        document.addEventListener("DOMContentLoaded", initialize, false);
    } else {
        window.attachEvent("onload",initialize);
    }
})();

After you include this JavaScript module in the page, the code will hook into the validation process and allow the developer to control the error messages, as shown in Figure 12.

Figure 12: Custom validation message

More Options for Input

As you've seen, HTML5 offers exciting new enhancements to form inputs and we'll continue to explore what HTML5 has to offer with "Working with HTML5 Web Forms: Autofocus and Placeholder Attributes." With HTML5's modern input types, additions to CSS that let you set style based on validation state, and new methods and attributes in JavaScript for controlling behavior in code, developers and designers now have a better approach to the task of getting data from the user.