HTML5 Forms: The Markup

This is the first in a three-part series about HTML5 web forms. We’ll cover the basic markup in this article before progressing to styling and the client-side JavaScript validation APIs. I recommend you read this even if you’re already familiar with forms — there are many new attributes and gotchas!

HTML forms may be mundane but they’re essential for the majority of web sites and apps. In HTML4, input fields were limited to:

  • input type="text"
  • input type="checkbox"
  • input type="radio"
  • input type="password"
  • input type="hidden" — for data the user cannot view
  • input type="file" — for uploads
  • textarea — for longer text entry
  • select — for drop-down lists
  • button — generally used for submitting a form, although input type="submit" and input type="image" could also be used.

Also:

  • CSS styling possibilities were limited,
  • custom controls such as date and color pickers had to be developed in code, and
  • client-side validation required JavaScript.

Additional HTML5 Input Types

A deluge of new input types have been introduced. These provide native input assistance and validation without any JavaScript code…

type description
email enter an email address
tel enter a telephone number — no strict syntax is enforced but line breaks will be removed
url enter a URL
search a search field with line breaks automatically removed
number a floating point number
range a control for entering an approximate value, typically represented by a slider
date enter the day, month and year
datetime enter the day, month, year, hour, minute, second and microsecond based on the current UTC timezone
datetime-local enter a date and time with no timezone
month enter the month and year with no timezone
week enter a week number with no timezone
time enter the time with no timezone
color specify a color

Input Attributes

Unless stated otherwise, input fields can have any of the following form-specific attributes. Several are Boolean attributes, that is, they do not require values, e.g

<input type="email" name="email" required />

although you can add them if you prefer a stricter XHTML-like syntax, e.g.

<input type="email" name="email" required="required" />

attribute description
name the input field name
value an initial value
checked checks a checkbox or radio input
maxlength the maximum length of the entered string. This can also be applied to textarea fields in HTML5
minlength the minimum length of the entered string. This is documented but, at the time of writing, browser support is poor and the attribute causes HTML validators to error. An alternative option is pattern=".{3,}" which would enforce at least three characters.
placeholder a subtle text hint shown in the input box
autofocus set focus to this (non-hidden) field when the page loads
required indicates that a value must be entered
pattern ensures a value adheres to a regular expression
min the minimum value permitted (numeric and date types)
max the maximum value permitted (numeric and date types)
step the value granularity. For example, input type="number" min="10" max="19" step="2" would only permit the values 10, 12, 14, 16 or 18.
autocomplete provides the browser with a hint for auto-completion, e.g. “billing email” or can be set to “on” or “off” to enable and disable accordingly
inputmode specifies the input mechanism. The most useful options:

  • verbatim — non-prose content such as usernames
  • latin — latin script such as search fields
  • latin-name — names, i.e. with initial letter capitalization
  • latin-prose — prose content such as messages, tweets, etc.
  • numeric — numeric input where number or range would not be appropriate, e.g. credit card numbers
size the size in characters for text or password inputs or pixels for email, tel, url or search inputs. Probably best avoided since you should use CSS to style fields.
rows number of text rows (textarea only)
cols number of text columns (textarea only)
list points to a set datalist options
spellcheck set to true or false to enable or disable spell checking
form the ID of the form which this input belongs to. In general, inputs should be nested inside a form, but this attribute permits an input to be defined anywhere on the page
formaction specifies a URI to override the form action when submitting (submit buttons/images only)
formmethod specifies GET or POST to override the form method when submitting (submit buttons/images only)
formenctype specifies the type of content when submitting (text/plain, multipart/form-data or application/x-www-form-urlencoded on submit buttons/images only)
formtarget specifies a target window/frame to override the form target when submitting (submit buttons/images only)
readonly the input value cannot be changed although it will be validated and submitted
disabled disables the input — no validation will occur and data will not be submitted

Note that date fields must always use YYYY-MM-DD for value, min and max attributes.

The following example requests a mandatory email which ends in @mysite.com and has focus when the page loads:

<input
  type="email"
  name="login"
  pattern="@mysite\.com$"
  autocomplete="email"
  autofocus
  required />

Datalists

A datalist contains a set of suitable options for any type of input, e.g.

<input type="text" name="browser" list="browsers" />

<datalist id="browsers">
  <option value="Chrome" />
  <option value="Firefox" />
  <option value="Internet Explorer" />
  <option value="Safari" />
  <option value="Opera" />
</datalist>

When datalist is supported, the browser presents auto-complete options when you start to type. The whole list is usually shown if you double-click the control or click the down arrow (if shown). Unlike a standard select drop-down, the user is free to override these choices and enter their own value.

It’s possible to set values and text like standard select options, e.g.

<option value="IE">Internet Explorer</option>

but be aware that implementations differ. For example, Firefox auto-completes on the text itself (Internet Explorer) while Chrome prefers the value (IE) and shows the text greyed out:

datalist

Datalists can be populated by JavaScript if you wanted to retrieve options via Ajax.

Disabling Validation

Validation for the whole form can be disabled by setting a novalidate attribute on the form element. Alternatively, you can set a formnovalidate attribute on the form’s submit button/image.

Remember also that setting an input’s disabled attribute will prevent validation on that field.

Output Fields

While we’re primarily discussing input types, HTML5 also provides read-only output options:

  • output — the result of a calculation or user action
  • progress — a progress bar (the value and max attributes define the status)
  • meter — a scale which can change between green, amber and red depending on the values set for the attributes value, min, max, low, high and optimum

Separating and Labeling Inputs

The whatwg.org form specification states:

Each part of a form is considered a paragraph, and is typically separated from other parts using <p> elements

Interesting. I normally use a div although I doubt it matters from a semantic perspective. A p tag is shorter although it’s possible you’ll need to apply a class to modify margins.

More importantly, you should use label elements either around or next to the input itself with a for attribute stating the input’s ID, e.g.

<p>
  <p>
  <label for="firstname">First name</label>
  <input type="text" id="firstname" name="firstname" placeholder="first name" required maxlength="20" />
</p>
 
<p>
  <label for="lastname">Last name</label>
  <input type="text" id="lastname" name="lastname" placeholder="last name" required maxlength="20" />
</p>
 
<p>
  <label for="email">Email address</label>
  <input type="email" id="email" name="email" placeholder="your@email.address" required maxlength="50" />
</p>
 
<p>
  <label>
    <input type="checkbox" name="newsletter" />
    Sign up for our newsletter
  </label>
</p>

No Standard Controls

There are no specific interface guidelines for browser vendors to follow. This is intentional: a typical desktop mouse-controlled date picker can be too small on a mobile device so the vendor can implement a touch-based alternative.

Browser Support

Not every input type and attribute is supported in all browsers. In general, most modern browsers from IE10+ include basics such as email and number. However, the date types are only supported in Webkit and Blink browsers at the time of writing.

The browser will revert to a standard text input when a specific type and ignore attributes when those values are not supported.

Always Use the Correct Type!

It’s important to use the correct input type for the data you’re requesting. That may seem obvious but you will encounter situations when you’ll be tempted to use a standard text input.

Consider dates. Support is patchy and this leads to implementation issues:

  1. The standard date input always returns dates in YYYY-MM-DD format regardless of how the date picker is presented in your locale.
  2. IE and Firefox will fall back to a standard text input, but your users may expect to enter values in US MM-DD-YYYY or European DD-MM-YYYY format.
  3. A JavaScript date picker such as the one in jQuery UI allows you to define a custom format — or even YYYY-MM-DD for consistency — but you cannot guarantee JavaScript will be enabled.

The easy solution is to abandon the HTML5 date input, revert to text and implement your own date control. Don’t. You will never create a custom date picker which works in all devices at all screen resolutions, supports keyboard, mouse and touch input and continues to operate when JavaScript is disabled. In particular, mobile browsers are often ahead of their desktop cousins and implement good touch-screen controls.

The HTML5 input types are the future. Use them and, if necessary, add JavaScript polyfills in situations where you require good cross-browser support. But remember to…

Validate Server-Side

Browser validation is not guaranteed. Even if you forced everyone to access using the latest version of Chrome you could never prevent:

  • browser bugs or JavaScript failures permitting invalid data
  • the user changing your HTML or scripts using browser tools
  • submission from systems outside your control, or
  • data interception between the browser and the server (certainly over HTTP).

Client-side validation never has and never will be a substitute for server-side validation. Validating user data on the server is essential. On the client, it’s a nice-to-have.

Finally, remember dates may be received in YYYY-MM-DD or whichever format you specified to the user (MM-DD-YYYY, DD-MM-YYYY, etc.) Check for digits in the first four characters or use native language/framework date parsing methods as necessary.

We’ve covered a lot in this article. In the next part we’ll look at form-related CSS properties.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Skattabrain

    Hi Craig, I think you mean “part 1 of 3″. Looking forward to the next 2. Thanks!

    • LouisLazaris

      Unfortunately, the “series” plugin we’re using seems to act really weird, so we can’t control what it says when future articles aren’t published yet.

      We’ve temporarily disabled it so we can look for an alternative or a fix.

  • Zachio

    Great read, looking forward to the next parts.

  • Carlos

    “Validating user data on the server is essential”
    There should be a virus, that every say 30 minutes on each developer computer would pop a message with this :P

    • Craig Buckler

      You’re right. Many developers are far too trusting of user resourcefulness and stupidity!

  • http://www.ericlin.me Eric Lin

    I learned something new today, thanks for the post…

  • Samer

    nice rich detailed summary, saves a lot of reading. nice work

  • CTN

    Can you add links to part 2 and part 3? I found this article extremely helpful.

    To build on this foundation, you can follow up this article with another 2:

    * creating forms with bootstrap (v3)

    * adding angular js for those magic professional touches.

    bootstrap is really awesome for styling modern professional looking forms and angular allows the web dev to use the additional form css that bootstrap offers for showing when fields are valid / invalid.

  • http://www.daveismyname.com/ David Carr

    is their any known libraries for unsupported browsers?