How to Build Cross-Browser HTML5 Forms

How to Build Cross-Browser HTML5 Forms

Tutorial Details
  • Technology: HTML5
  • Difficulty: Moderate
  • Estimated Completion Time: 1 hour

Final Product What You'll Be Creating

In this tutorial, we’re going to take a look at how to serve HTML5 forms to modern browsers, while compensating for older browsers by using a mix of Webforms2, Modernizr, jQuery UI and assorted jQuery Plugins.


Introduction

HTML5 powered forms provide a great deal of semantic markup, and remove the need for a lot of JavaScript.

One of the first efforts toward HTML5 was WHATWG’s Web Forms 2.0, originally called XForms Basic. The spec introduced new form controls and validation, among other things. Later, it got incorporated into HTML5, and was subsequently stripped of the repetition model, resulting in what we know today as HTML5 Forms.

The ever-present issue, backward compatibility, still remains a headache though, unfortunately. Developers have to deal with the dreaded Internet Explorer, which, as you might have guessed, doesn’t provide much support for the latest advancement in forms – even in the latest available beta of IE9. Older versions of IE? Fagetaboutit.

Nonetheless, we want to use these new features, and use them, we will! Today, we’re going to look at some of these new elements. We’ll check whether the browser support these features, and if not, provide fallbacks using CSS and JavaScript.


Tool: Modernizer

We’ll be providing fallbacks only to browsers that don’t support HTML5 forms, or certain parts of them. But instead of relying on browser sniffing, the proper technique is to use feature detection. We’ll use the popular Modernizr library.

Modernizr is a small JavaScript library that tests the current browser against a plethora of HTML5 and CSS3 features.

If you want to learn more about Modernizr, you might check out “A Video Crash-Course in Modernizr” premium tutorial available on the Tuts+ Marketplace.


Tool: Webforms2

Webforms2 is a JavaScript library by Weston Ruter, which provides a cross-browser implementation of the “previous” version of HTML5 forms, the “WHATWG Web Forms 2.0″ specification.

We’ll be using it for validation and extending functionality for current elements.

<script type="text/javascript" src="webforms2/webforms2-p.js"></script>

Widget: Slider

The spec describes the range input as an imprecise control for setting the element’s value to a string representing a number.

<input type="range" name="slider">

Here’s a preview of how it looks in Opera 10.63:

Range input in Opera

To provide fallback for other browsers, we’ll use jQuery UI’s slider widget.

First, we create our initializing function, which creates the slider from the input range element.

var initSlider = function() {
	$('input[type=range]').each(function() {
		var $input = $(this);
		var $slider = $('<div id="' + $input.attr('id') + '" class="' + $input.attr('class') + '"></div>');
		var step = $input.attr('step');

		$input.after($slider).hide();

		$slider.slider({
			min: $input.attr('min'),
			max: $input.attr('max'),
			step: $input.attr('step'),
			change: function(e, ui) {
				$(this).val(ui.value);
			}
		});
	});
};

We create a new <div> element for each of our range inputs, and call the slider on that node. This is because jQuery UI’s slider will not work by calling it directly on the input element.

Note that we’re getting attributes from the input, such as min, max and step,, and are then using them as parameters for the slider. This helps our fallback slider mimic the real HTML5 slider in functionality.

Next, we’ll use Modernizr to determine if the current browser supports this input type. Modernizr adds classes to the document element (html), allowing you to target specific browser functionality in your stylesheet. It also creates a self-titled global JavaScript object which contains properties for each feature: if a browser supports it, the property will evaluate to true and if not, it will be false.

With that knowledge, to detect support for input types, we’ll use Modernizr.inputtypes[type].

if( !Modernizr.inputtypes.range ){
	$(document).ready( initSlider );
};

If there’s no support for the range input, we attach the initSlider function to jQuery’s document.ready, to initialize our function after the page has loaded.

This is how the slider should look in a browser without native support for the range input.

jQuery UI Slider as fallback for input type range

Widget: Numeric Spinner

To quote Mark Pilgrim:

Asking for a number is trickier than asking for an email address or web address.

That’s why we’re provided with a separate form control which specifically deals with numbers: the numeric spinner, also called the numeric stepper.

<input type="number" value="2">

At the time of this writing, it is supported by Opera and Webkit-based browsers; here’s a snapshot from Opera 10.6.

Number input in Opera

Because jQuery doesn’t provide a numeric spinner, we’ll instead use a jQuery plugin by Brant Burnett, built as a jQuery UI widget.

We implement the same technique as before; build out the function to create the spinner, test with Modernizr, and attach the function to $(document).ready.

var initSpinner = function() {
	$('input[type=number]').each(function() {
		var $input = $(this);
		$input.spinner({
			min: $input.attr('min'),
			max: $input.attr('max'),
			step: $input.attr('step')
		});
	});
};

if(!Modernizr.inputtypes.number){
	$(document).ready(initSpinner);
};

Because number inputs also support min, max and step, we get the attributes from the field, and use them as parameters for initializing the numeric spinner plugin.

And our fallback widget looks like so:

jQuery UI Spinner as fallback for input type number

Widget: Date Picker

There are no less than six input types to serve as date pickers.

  • date
  • month
  • week
  • time
  • datetime and
  • and datetime-local

At the time of this writing, the only browser that properly supports them is Opera, versions 9+.

<input type="date">
<input type="month">
<input type="week">
<input type="time">
<input type="datetime">
<input type="datetime-local">

For now, we’ll only provide fallback for the date input, using the jQuery UI Datepicker. Feel free to use any other plugin to completely mimic the functionality of the HTML5 date picker input in your implementation.

var initDatepicker = function() {
	$('input[type=date]').each(function() {
		var $input = $(this);
		$input.datepicker({
			minDate: $input.attr('min'),
			maxDate: $input.attr('max'),
			dateFormat: 'yy-mm-dd'
		});
	});
};

if(!Modernizr.inputtypes.date){
	$(document).ready(initDatepicker);
};
jQuery UI Datepicker as fallback for date input

Widget: Color Picker

Right now, no browser provides support for the color input. So, until they catch up, they’ll all need to use our fallback technique.

<input type="color">

We’ll use Stefan Petre‘s ColorPicker jQuery plugin, since jQuery UI does not provide one with the base pack yet.

var initColorpicker = function() {
	$('input[type=color]').each(function() {
		var $input = $(this);
		$input.ColorPicker({
			onSubmit: function(hsb, hex, rgb, el) {
				$(el).val(hex);
				$(el).ColorPickerHide();
			}
		});
	});
};

if(!Modernizr.inputtypes.color){
	$(document).ready(initColorpicker);
};

And our result:

jQuery ColorPicker as fallback for color input

Input Type: Search

The new search input type is implicitly used for semantics, but could provide a lot of interesting functionalities in the future.

<input type="search">

Currently, only Webkit-based browsers offer support for this feature. The spec also supports a results attribute to display a number of searched terms in a dropdown.

It should look like this on Safari on OS X:

Search input on Safari OS X

The rest of the browsers display this as a standard text field, so you may confidently use it with the standard markup.


Input Type : URL and Email

These two input types, url and email, are used for validation purposes. They can be particularly useful in mobile browsers, where the on-screen keyboard layout can be changed to suit the focused field. This is already implemented in Safari on iOS(iPhone, iPad, iPod), and some versions of Android.

<input type="email">
<input type="url">

These input types can be implemented by Webforms2 in other browsers.

You can freely use these types in your new projects, as they fallback to simple textboxes. On your phone, you’ll find that the keyboard changes accordingly, if you supply these types to your inputs.


Attribute: Required Fields

The new spec introduces the very handy required attribute. Instead of using fancy JavaScript to take care of our required fields, now we can easily use this attribute.

<input type="email" required>

For browsers that don’t support this attribute, we can again use Webforms2. So, since we’ve included it from the start, there’s nothing to worry about.

Note: Be sure to assign a name attribute to your form elements, or the required attribute will not take effect.


Attribute: Pattern

The pattern attribute is used for field validation and accepts values only if they match a specific format, defined with regular expressions. If the entered value does not match the pattern, the form won’t submit.

For example, to validate a phone number, we’d have to use the following pattern, or regular expression:

<input type="text" name="Tel" pattern="^0[1-689][0-9]{8}$">

The pattern attribute can be implemented in browsers that don’t support it, by using Webforms2.


Attribute: Autofocus

The autofocus attribute does just what it says: automatically focuses one of our controls. It is currently supported in Webkit-based browsers(Safari, Chrome, etc.) and Opera. Remember: only one form control can receive this attribute.

<input type="email" autofocus>

Webforms2 takes care of the implementation in unsupported browsers.


Attribute: Placeholder

The placeholder attribute is something we’ve been doing with JavaScript for years. It adds a piece of information about the field, like a short description, that disappears when the field is focused.

<input name="name" placeholder="First Name">

This attribute is supported by the latest Beta Firefox and Webkit browsers.

To mimic the behavior in older browsers, we’ll use the Placehold jQuery plugin, by Viget’s Design Lab.

var initPlaceholder = function() {
	$('input[placeholder]').placehold();
};

if(!Modernizr.input.placeholder){
	$(document).ready(initPlaceholder);
};

Attribute: Min, Max and Step

The min, max and step input attributes specify constraints for certain form controls, such as the date picker, number, and range. You can surely guess the purpose of min and max from their names. The step attribute specifies the multiple range for each click, or “step.” For isntance, if the step value is 2, the accepted values could be 0, 2, 4, and so on.

<input type="range" name="slider" min="0" max="20" step="5" value="0">

These attributes are only supported by Opera and Webkit browsers right now, and are implemented, as fallback for other browsers, by Webforms2.


Conclusion

We’ve learned today that creating forms and providing fallback for most of the new additions is a fairly easy task. If people are still trying to scare you from using HTML5 today, pay no attention to them; start using the awesome tools you have at your disposal right now!

Be sure to also check out Zoltan “Du Lac” Hawryluk‘s great html5Widgets, which provide similar solutions, with native JavaScript widgets.


Further Reading

Add Comment

Discussion 46 Comments

  1. reven says:

    nice, but in Opera 10 the color picker appears twice (Operas builtin one and the javascript one).

  2. Jings says:

    Really Nice, thanks!

  3. Jings says:

    Really Nice, thanks! :)

  4. bogdan says:

    Congrats, conationalule :)

  5. Nice, but the slider don’t work on iPad.

  6. Jason says:

    Opera 11 shows 2 color pickers :)

  7. IMAMO says:

    As Jason said problem in opera also I notice problem with date picker in webkit browsers (Safari&Chrome) not working. And the file html5forms.js is missing in download file. But hey, thanks for this great tutorial and useable tips as any other previous posts at nettuts!

  8. I’m seeing the Numeric Spinner is showing 2 sets of icons on Safari 5.0.3 / Mac…

  9. Harry Edwards says:

    Great Tut but the form seems very buggy on an iPhone 4, the URL/email inputs’ keyboards keep closing when you try and type, tis a shame the ‘full’ webkit browser doesn’t seem to be so full on the iPhads :-(

    On to something completely different could you do an article about your variable width layout?? Fascinated to know how you make the site nice and wide on large monitors but make the ads & content narrower on smaller monitors/mobiles..?

    Cheers!

  10. Ryan says:

    Can I suggest not recommending the use of webforms2.js. Weston wrote this over 4 years ago when webforms 2.0 was a separate specification, it’s now part of HTML5 spec (and quite different). It implements old features, such as the repetition model, that have since been removed from the merged spec. I believe there are plans to bring it up to spec but this have not been done yet.

    The webforms.js initial check for support returns true even in supporting browsers.

    if(document.implementation && document.implementation.hasFeature &&
    !document.implementation.hasFeature(‘WebForms’, ’2.0′)){ }

    This will run through the webforms javascript regardless if the browser really supports HTML5 Forms chapter or not. In fact the only browser that will return false from the above statement is Opera as they were the only ones to implement webforms2.

    When I looked at this several months back, behaviour in IE versions was sporadic. In Chrome and IE8 every field regardless if it has min, max or step attributes has them with the value as undefined. The numeric spinner in IE8 will never validate and the error message will say it needs to be between 1 and undefined…

    In fact each browser behaves differently with your demo.

    This is truly a poor article. I expect much higher quality from Nettuts.

    • Author

      Ryan,
      I understand where you’re coming from, and I’m aware of the issues with webforms2, that’s why I advise using Zoltan’s version of webforms2, as he has fixed a couple of them.
      http://www.useragentman.com/blog/2010/07/27/cross-browser-html5-forms-using-modernizr-webforms2-and-html5widgets/

      Also, there’s a planned rewrite of the script that will be based on the new spec. Sadly, there’s no clear timeline for when that will happen.

      I’m also very much aware of your H5F Library. It’s an awesome library, but it’s targeted at the more advanced developers, while, in the article, I’ve tried to keep things as simple as possible, for the medium and beginner web developer.

      The article is mostly focused on the new form widgets, rather than validation and other new form features present in HTML5, that’s why I’m pushing Modernizr as much as possible to check features.

  11. Adrian Cătălin says:

    Mulțumim Cristian! / Thank you, Cristian!
    Great tutorial!

  12. Vanderhill says:

    Excellent jQuery tutorial on enhancing webforms! Thanks!

  13. netblonde says:

    wow, HTML 5 makes working with forms a lot easier, thanks for the tutorial.

  14. Adel says:

    There is a little typo in the “Introduction” section.
    The last word of the second paragraph is “Fagetaboutit”, while it should be “Forget about it”.

  15. Ghita says:

    How know how I make an calendar as the above calendar??

  16. Edward Longman says:

    Thank you exellent tutorial but what you didn’t point out is that you still MUST do serverside validation because these systems can be bypassed

  17. Ben Howdle says:

    Brilliant tutorial, HTML5 has to be the way to go!

    If anyone is interested in jQuery AJAX powered Mail Forms, check out: http://blog.twostepmedia.co.uk/send-html-form-results-in-an-email-from-php-using-jquery-ajax/

    Thanks Cristian Colceriu for the cool tut

  18. Finally I can think about using the more adventurous parts of the HTML5 form spec. Thanks a lot, especially for touching on the pattern attribute, I think I can think of some really good uses for that.

  19. Bill says:

    How is this cross browser, a lot of the stuff doesnt work in ie6 and it looks different in chrome only firefox looked like the comp.

  20. Edward Longman says:

    Mad as this sounds, this actually looks better in ie than it does in google chrome and safari
    this is how it goes in order of awsomnness
    Mozilla firefox
    Internet Explorer (8)
    Safari
    Chrome :(

  21. mechamonkey says:

    Absolutely fantastic article.

    I’d been looking for something like this to explain how to provide better backwards compatibility for HTML5 forms with not much success, this is absolutely spot on, thank you.

    Now to show ‘they who are above you’ and see if I can finally convince them to move forward.

  22. Steve Ndeso says:

    Great HTML5 Tutorial .. nice

  23. HTML5 Elite says:

    Love it – thanks for the tutorial.

  24. Abijith K says:

    great..Will it work in IE 6 too ? I think some 1% people are still using IE 6 ?? :(

  25. Simple solution says:

    Well topic is misleading. You can’t create sth realy cross browser in html5 so far. And you don’t realy need html5 to use java scripts, jquery plugins and widgets.

    Personaly i would suggest niceforms v2. Nice little script that make forms look same on all browsers (except ie6, but who cares about it anymore)

  26. Nikki says:

    Am I the only one thinking that 8 (10?) scripts/369.9 KB of JavaScript is a bit excessive for this?

  27. Katherine says:

    your demo slider does not work on ipad

  28. Mustafa says:

    excellent work ty.

  29. Ashish says:

    it’s fyn, but IE and opera creates some problem….

    Chrome doesn’t shows the valiations…

    Opera has same problem as mentioned above many times regarding the color box…

  30. shobz says:

    Hey its not a cross browser Form :/ javascript will be required any how for sliders color pickers date pickers even validations bla bla bla… may be its gud with new browsers but i’ve tested in IE7 and cant see slider, date picker and that numeric one.. ;p

    HTML5 is not for every one :P

  31. Stephen Page says:

    All of this can be done with just jQuery and jQueryUI – I’m with Nikki that the extra files seem superflous.

  32. Ahmed Fouad says:

    not compatible with IE7, that seems strange to me but this selector results’ length is 0 just in IE
    $(‘input[type=range]‘), IE7 considers all the input in the page as ‘text’

    Any ideas?

  33. Reviews says:

    Great stuff, good tutorial. This is very user friendly

  34. Anna says:

    Very Cross-Browser form, especially in IE and Opera. I do not understand why they use the library Modernizr, in IE on the calendar is no shadow and border-radius. Please correct errors or remove from the title of the article Cross-Browser HTML5 Forms, and write, who wrote the post for 10 minutes and the laptop was only one browser Safari.

  35. Good tutorial :)
    but the webforms2 plugin errors are very ugly, is there any other alternative?
    Or any way to call a function if it catches the error?

  36. I really know nothing about English, so, i can’t understand all those words, hoho~

  37. Kasko says:

    Thank you very much. The clause has very much helped. The clause has very much helped.

  38. Kursad says:

    Great stuff. Good tutorial.

  39. Roes Wibowo says:

    Finally, I found tutorial that is explain to use modernizer.. There isn’t tutorial on official site of modernizer.. This is very useful, thanks..

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.