HTML5 Form Tutorial

In part one of this four five part tutorial, we’re going to create a contact form using the new HTML5 input attributes.  It must be stated outright that as browser support is still lacking for these attributes, this tutorial is for illustrative purposes only – I wouldn’t recommend using the new input types in a production environment yet.  That being said, it’s interesting to know what’s in store for us just around the corner.  Let’s get started.

HTML Template

This is the base template we’re going to use for the form.

<!DOCTYPE html>
<html lang="en">
  <meta charset="utf-8" />
  <title>Contact Form</title>

As you can see, we’re using the HTML5 doctype.  Notice that the meta tag defining the character set is shorter than in previous versions of the language:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

In HTML5, the http-equiv and content attributes are superfluous, so we can strip those out.  The same goes for the type attribute in the style and script tags – we no longer need to define the type as text/javascript or text/css, as it’s implied by the tag name.

Input Types

Horse and PloughThe input element, as specified in HTML4, has ten values for it’s type attribute: button, checkbox, file, hidden, image, password, radio, reset, submit, and text.  The text input in particular has become the work-horse of HTML forms, used to capture a wide range of alphanumeric data.  This will change with the adoption of the new HTML5 input types.  In the same way that div is set to be superceded by header, nav, article, section, aside, and footer, the text attribute will be displaced by more semantic type attributes (search, tel, url, email, datetime, date, month, week, time, datetime-local, number, color and range) that accurately describe the data to be entered into them.

Contact Form

The form we’re going to create will not be a run-of-the-mill contact form, it will be aimed at satisfying the needs of a freelancer.  It’s purpose will be to collect enquiries from clients regarding potential projects – this enables us to examine how these new input types might work in a real-world setting.

The data our form will capture is as follows (the input type we will use is in brackets):

  • Name (text)
  • Company (text)
  • Email (email)
  • Telephone (tel)
  • Website (url)
  • Type of Project (select)
  • Projected Completion Date (date)
  • Estimated Budget (number)
  • Additional Details (textarea)
  • Please contact me by Email | Phone (radio)
  • Best time to contact? (time, disabled unless ‘contact by phone’ selected)

We’re going to seperate these properties into 3 fieldsets to make the form a little easier on the eye, and create the label and inputs for them.  The markup will look like this:

    <p><label>Name</label><input type="text" /></p>
    <p><label>Company</label><input type="text" /></p>
    <p><label>Email</label><input type="email" /></p>
    <p><label>Telephone</label><input type="tel" /></p>
    <p><label>Website</label><input type="url" /></p>
    <p><label>Type of Project</label></p>
        <option>HTML/CSS Build</option>
        <option>Custom jQuery Plugin</option>
        <option>Wordpress Template</option>
    <p><label>Projected Completion Date</label><input type="date" /></p>
    <p><label>Estimated Budget (&pound;)</label><input type="number" /></p>
    <p><label>Additional Details</label><textarea rows="5"></textarea></p>
    <p class="contact-method">
      <span>Please contact me by&hellip;</span>
      <label><input type="radio" value="Phone" checked="checked" /> Phone</label>
      <label><input type="radio" value="Email" /> Email</label>
    <p><label>Best time to contact?</label><input type="time" /></p>
    <p><input class="submit" type="submit" name="submit" /></p>

Notice that we’ve added a class to the submit button and to the paragraph containing the contact method.  In an ideal world we’d be able to use a pseudo class like nth-child to style these elements, but it isn’t supported in IE6&7, so we’ll stick with normal classes for now.  We’re going to add a bit of basic CSS, just to make the form look a little nicer for the time being.

* { margin: 0; padding: 0 }
form { width: 460px; padding: 20px; color: #333333; font-family: Verdana, Geneva, sans-serif; font-size: 12px; margin: 0 auto }
fieldset { border: 0; padding: 10px; margin-bottom: 10px; background: #F6F6F6 }
legend { padding: 5px 10px }
label, span { float: left; clear: left; display: block; width: 180px; padding-right: 20px; text-align: right }
input, textarea, select { float: left; width: 200px }
.submit { width: 100px; float: right; margin-right: 37px }
select { width: 202px }
p { overflow: hidden; margin-bottom: 10px }
.contact-method label { clear: none; width: auto }
.contact-method input { float: none; width: 20px }

We’ll revisit the CSS in the next part of this tutorial.

Form Accessibility

In it’s present state, the form isn’t very accessible to people using screen readers, so we’re going to make some improvements by adding a legend to the fieldset, adding input names IDs (correction 01/05/11: names for php enabled forms, IDs for accessible form controls.  With thanks to Nick :)), and associating the input with it’s counterpart label using the ‘for’ attribute.  A brief note – there is some debate between accessibility experts on whether it’s better to wrap the input with it’s label, rather than creating sibling elements.  I think it’s a matter of personal preference – using the ‘for’ attribute creates an explicit association between the two elements.

As this form is contained within a basic page, it’s not necessary to define tab indices; the flow of the page is pretty basic and should tab in the correct order.  However, if you’re working with more complex markup, other elements on the page may interfere with the flow of the document – in this situation it’s best practice to define tab indices to assist with navigation of the page.

Once the modifications are complete, the markup will look like this:

    <legend>Contact Details</legend>
    <p><label for="name">Name</label><input id="name" type="text" /></p>
    <p><label for="company">Company</label><input id="company" type="text" /></p>
    <p><label for="email">Email</label><input id="email" type="email" /></p>
    <p><label for="telephone">Telephone</label><input id="telephone" type="tel" /></p>
    <p><label for="website">Website</label><input id="website" type="url" /></p>
    <legend>Project Details</legend>
      <label for="project-type">Type of Project</label>
      <select id="project-type">
        <option>HTML/CSS Build</option>
        <option>Custom jQuery Plugin</option>
        <option>Wordpress Template</option>
    <p><label for="completion-date">Projected Completion Date</label><input id="completion-date" type="date" /></p>
    <p><label for="project-budget">Estimated Budget (&pound;)</label><input id="project-budget" type="number" /></p>
    <p><label for="project-details">Additional Details</label><textarea id="project-details" rows="5"></textarea></p>
    <legend>Contact Preferences</legend>
      <span>Please contact me by&hellip;</span>
      <label><input id="contact-method" type="radio" value="Phone" checked="checked" /> Phone</label>
      <label><input id="contact-method" type="radio" value="Email" /> Email</label>
    <p><label for="contact-time">Best time to contact?</label><input id="contact-time" type="time" /></p>
    <p><input type="submit" id="submit" value="Submit Form" /></p>

View Demo

Next time, we’ll be looking at sprucing our form up a bit with CSS. Stay tuned.

Photo Credit: Trevor Dennis on Flickr

HTML5 Doctype: Make the Switch!

There is a great deal of confusion surrounding the implementation of HTML5 amongst some developers.  Some believe that we shouldn’t be using HTML5 because it’s not ‘ready’, and that using the HTML5 doctype is dangerous because older browsers don’t support HTML5.

Lets be clear: you can switch to using the HTML5 doctype in your projects right now; the new features may not be supported in older browsers.  For example, IE doesn’t support the new structural elements (header, nav, article, section, aside, footer), and needs a little CSS & JavaScript support to get them to work.  The doctype however works perfectly well.  The main practical effect of switching

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">


<!DOCTYPE html>

is that standards mode is triggered.  There’s no excuse for not using a strict doctype in either case.

So why make the switch?  There are two main reasons, the first is to simplify your markup.  You get to write less code, and shave a few bytes off the document size.  The second is to enable you to use some of the features of HTML5 in newer browsers now, whilst ensuring graceful degradation in older browsers.

It’s analogous to the situation with CSS2.1/CSS3 in some respects.  You might create a fancy button with a gradient background, rounded corners and text shadow with CSS3 for newer browsers; the same button in IE would be square, have a flat background colour and no text shadow.  You have the option to prop up IE with graphics in a conditional stylesheet, or just leave it like it is.  It’s the same case, for example, with the new date input type – this will gracefully degrade into a text input in browsers that don’t support it; it’s up to you whether you want to implement a JavaScript date picker or not.

Just because some features aren’t supported by older browsers, doesn’t mean we can’t use them!  If we thought like that then we’d all still be limited to CSS1, as IE8 is the only browser to support CSS 2.1 completely.

What I’m listening to right now: Radiohead – “Where I End and You Begin”