{"id":4472,"date":"2012-05-17T22:45:03","date_gmt":"2012-05-18T02:45:03","guid":{"rendered":"http:\/\/www.useragentman.com\/blog\/?p=4472"},"modified":"2012-11-06T12:12:05","modified_gmt":"2012-11-06T16:12:05","slug":"cross-browser-styling-of-html5-forms-even-in-older-browsers","status":"publish","type":"post","link":"http:\/\/www.useragentman.com\/blog\/2012\/05\/17\/cross-browser-styling-of-html5-forms-even-in-older-browsers\/","title":{"rendered":"Cross Browser Styling of HTML5 Forms &mdash; Even In Older Browsers."},"content":{"rendered":"<div class=\"importantNotes\">\n<strong>Note:<\/strong> For an introduction to HTML5 Forms, you may want to also read my original post, <a href=\"https:\/\/www.useragentman.com\/blog\/2010\/07\/27\/creating-cross-browser-html5-forms-now-using-modernizr-webforms2-and-html5widgets\/\">Creating Cross Browser HTML5 Forms Now, Using modernizr, webforms2 and html5Forms<\/a> which has been updated to reflect changes in the latest version of the html5Forms.js package, including the ones described in this article.  I have also written about <a href=\"https:\/\/www.useragentman.com\/blog\/2012\/11\/05\/css3-pseudo-classes-and-html5-forms-their-limitations-and-a-possible-solution\/\">CSS3 Pseudo-Classes and HTML5 Forms: Their Limitations and a Possible Solution<\/a>, which may be of interest if you need advanced styling of HTML5 Forms that the specification doesn&#8217;t handle.\n<\/div>\n<p><a name=\"#top\" id=\"#top\"><\/a><\/p>\n<div style=\"width: 260px\" class=\"wp-caption alignleft\" >\n<p><strong>Note:<\/strong> <img decoding=\"async\" class=\"inline\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/asterisk_orange.png\" alt=\"*\" \/> denotes a required field.<\/p>\n<form action=\"https:\/\/www.useragentman.com\/testForm.php\" id=\"test1\" class=\"testValidity\" data-webforms2-force-js-validation=\"true\">\n<table class=\"formTable\">\n<tr>\n<th>Name: <\/th>\n<td><input type=\"text\" name=\"name\" value=\"\" required=\"required\" \/><\/p>\n<div class=\"description\"><\/div>\n<\/td>\n<\/tr>\n<tr>\n<th>Phone: <\/th>\n<td><input type=\"tel\" name=\"phone\" required=\"required\" value=\"\" pattern=\"[0-9]{3}-?[0-9]{3}-?[0-9]{4}\" placeholder=\"e.g. 416-555-1234\" data-errormessage=\"The phone number must be in the following format: 555-555-5555.\"\/><\/p>\n<div class=\"description\"><\/div>\n<\/td>\n<\/tr>\n<tr>\n<th>Email: <\/th>\n<td><input type=\"email\" name=\"company\" required=\"required\" value=\"\"  \/><\/p>\n<div class=\"description\"><\/div>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><input type=\"submit\" value=\"Submit Information\"\/><\/td>\n<\/tr>\n<\/table>\n<\/form>\n<p class=\"wp-caption-text\">An example HTML5 Form with validation.  Interact with it, and you will see the form will detect when the user has put in valid information as he types.  You will also note that if the form is submitted when some of the data is invalid, it will show friendly error messages.<\/p>\n<\/div>\n<p><strong>HTML5 Forms<\/strong> is probably the most practical and, I believe, <strong>will be the most commonly used module of the HTML5 spec.<\/strong>  With it, you can create <strong>great looking, easy-to-use forms<\/strong> that can <strong>validate each field as a user types.<\/strong>  Try the example on the left to see how this validation works. Then try to submit the form when it contains errors &mdash; you will see a <strong>nice, friendly error message beneath your first mistake.<\/strong>  Nice, isn&#8217;t it?  Many of the modern browsers (i.e. Firefox 4.x+, Chrome 17+<sup><a href=\"#foot1\">1<\/a><\/sup>, Opera 10.x+, IE 10+) support the HTML5 Forms spec natively, and it is possible to add support to the other browsers (Safari<sup><a href=\"#foot1\">1<\/a><\/sup> and IE 9.0-) using <strong>HTML5Forms.js, the updated version of my HTML5Widgets package I published in 2010.<\/strong>  It includes a modified build of Weston Ruter&#8217;s webforms2 that mimics the behavior of the newer native implementations of the HTML5 Forms specification. After you read this article, I would suggest first reading my initial blog post, <a href=\"https:\/\/www.useragentman.com\/blog\/2010\/07\/27\/cross-browser-html5-forms-using-modernizr-webforms2-and-html5widgets\/\">Creating Cross Browser HTML5 Forms Now, Using modernizr, webforms2 and html5Widgets<\/a> (updated, of course, to be in sync with the new features of the new HTML5Forms.js package) so that you can become familiar with the other parts of the HTML5 Forms specification.<\/p>\n<h2>Before Getting Started<\/h2>\n<p>You will need to download the HTML5Forms.js JavaScript library to add support for older browsers that don&#8217;t support HTML5 Forms natively.  When you download the package, all you need to do is add the following tags to the head of your document:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n &lt;script type=\"text\/javascript\" \r\n      src=\"\/path\/to\/shared\/js\/modernizr.com\/Modernizr-2.5.3.forms.js\"&gt;\r\n &lt;\/script&gt;\r\n\r\n &lt;script type=\"text\/javascript\"\r\n          data-webforms2-support=\"validation\" \r\n          src=\"\/path\/to\/html5Forms\/shared\/js\/html5Forms.js\" &gt; \r\n          \r\n &lt;\/script&gt;\r\n<\/pre>\n<\/blockquote>\n<p>HTML5Forms.js includes a custom build of <a href=\"http:\/\/modernizr.com\/\">Modernizr<\/a> that includes only the Form element detection routines.   If you want, you can include the full blown version of Modernizr or your own custom build of it instead, as long as it has HTML5 Forms support.  <strong>Note that the <code>script<\/code> tag that includes html5Forms has a <code>data-webforms2-support<\/code> attribute.<\/strong>   This is used to tell the script the parts of the specification that need to be supported.  If the browser doesn&#8217;t support that part of the spec, load the additional scripts needed to add support.  In this case, <code>data-webforms2-support<\/code> is set to <code>\"validation\"<\/code> which tells html5Forms to load webforms2 polyfill to add support for older browsers, which is included with HTML5Forms.js.  For more information about the other values that can be added to <code>data-webforms2-support<\/code>, please read my previous article of HTML5Widgets.<\/p>\n<p>So&#8230; now that we got the polyfill out of the way, let&#8217;s see what HTMl5 Forms can do.<\/p>\n<h2>Styling Validation Messages<\/h2>\n<p>Let&#8217;s say you have a form field that is supposed be used to input a North American Phone Number:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;input type=\"text\" name=\"phonenum\" value=\"\"  \/&gt;\r\n<\/pre>\n<\/blockquote>\n<p>Now let&#8217;s say you want to validate the form element on the client side.  In HTML5, all you need to do is insert the following HTML into your <code>&lt;input&gt;<\/code> element:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;input type=\"tel\" name=\"phonenum\" value=\"\" \r\n          <span class=\"hilite\">pattern=\"[0-9]{3}-?[0-9]{3}-?[0-9]{4}\"<\/span>\r\n          <span class=\"hilite\">required placeholder=\"e.g. 416-769-7093\"<\/span> \/&gt;\r\n<\/pre>\n<\/blockquote>\n<p>The <code>required<\/code> attribute forces the user to fill out this form field.  The <code>pattern<\/code> attribute ensures the form will be submitted when the text inside the form field matches the a North American phone number using the attribute&#8217;s regular expression (if you aren&#8217;t familar with regular expressions, take a look at <a href=\"http:\/\/www.javascriptkit.com\/javatutors\/re.shtml\">Regex Tutorial<\/a>).  The <code>placeholder<\/code> attribute is there to give the user an idea about how the data should be formatted (presented in English, since most people can&#8217;t resolve regular expressions inside their head.  My brother can, but then again, he really isn&#8217;t like most people).<\/p>\n<p>To see how this works in practice, try entering in valid and valid phone numbers into the form field below to see what happens when you try to submit:<\/p>\n\r\n<form action=\"https:\/\/www.useragentman.com\/testForm.php\" class=\"wf2-keep-native-style\">\r\n<table class=\"formTable\">\r\n<tr>\r\n\t<th>Phone Number :<\/th>\r\n\t<td><input type=\"tel\" name=\"phonenum\" value=\"\" pattern=\"[0-9]{3}-?[0-9]{3}-?[0-9]{4}\" required placeholder=\"e.g. 416-769-7093\" \/>\r\n\t<\/td>\r\n<\/tr>\r\n<tr>\r\n\t<th>Zip Code :<\/th>\r\n\t<td><input type=\"text\" name=\"zipc\" value=\"\" pattern=\"[0-9]{5}(-?[0-9]{4})?\" required placeholder=\"e.g. 90210\" \/>\r\n\t<div class=\"description\"><\/div>\r\n\t<\/td>\r\n<\/tr>\r\n<tr>\r\n<td ><\/td>\r\n<td>\r\n<input type=\"submit\" value=\"Submit\" \/>\r\n<\/td>\r\n<\/tr>\r\n<\/table>\r\n<\/form>\r\n<p>See the nice and friendly &#8220;cartoon bubble&#8221; that appears when the phone number is not formatted correctly?  This is HTML5 Form Validation in action.  Pretty cool, but you will see the browsers don&#8217;t style them in exactly the same way:<\/p>\n<table class=\"screenshots\"  >\n<thead>\n<tr>\n<th ><\/th>\n<th >Windows<\/th>\n<th >Mac<\/th>\n<th >Linux<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th >Firefox 4.0+<br \/>(native support)<\/th>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Windows Firefox\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/validation-firefox4-windows.png\" alt=\"Screenshot of range field for Windows Firefox\"><\/td>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Mac Firefox\" src=\"\/blog\/wp-content\/uploads\/2012\/03\/validation-firefox4-mac.png\" alt=\"Screenshot of range field for Mac Firefox\"><\/td>\n<td ><img decoding=\"async\" title=\"Screenshot of range field for Linux Firefox\" src=\"\/blog\/wp-content\/uploads\/2012\/05\/validation-firefox4-linux.png\" alt=\"Screenshot of range field for Windows Firefox\"><\/td>\n<\/tr>\n<tr>\n<th >Safari 5.x- <br \/> (polyfill)<\/th>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Windows Safari\" src=\"\/blog\/wp-content\/uploads\/2012\/05\/validation-safari-windows.png\" alt=\"Screenshot of range field for Windows Safari \"><\/td>\n<td ><img decoding=\"async\" title=\"Screenshot of range field for Windows Safari\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/validation-safari-mac.png\" alt=\"Screenshot of range field for Mac Safari \"><\/td>\n<td >Not Applicable<\/td>\n<\/tr>\n<tr>\n<th >Chrome 17+<br \/>(native support)<\/th>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Chrome Windows\" src=\"\/blog\/wp-content\/uploads\/2012\/05\/validation-chrome-windows.png\" alt=\"Screenshot of range field for Chrome Windows\"><\/td>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Chrome Mac\" src=\"\/blog\/wp-content\/uploads\/2012\/03\/validation-chrome-mac.png\" alt=\"Screenshot of range field for Chrome Mac\"><\/td>\n<td  >\n<img decoding=\"async\" title=\"Screenshot of range field for Linux Chrome\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/validation-chrome-linux.png\" alt=\"Screenshot of range field for Linux Chrome\" ><\/td>\n<\/tr>\n<tr>\n<th >Opera<br \/>(native support)<\/th>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Windows Opera\" src=\"\/blog\/wp-content\/uploads\/2012\/05\/validation-opera-windows.png\" alt=\"Screenshot of range field for Windows Opera\"><\/td>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Mac Opera\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/validation-opera-mac.png\" alt=\"Screenshot of range field for Mac Opera\"><\/td>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Linux Opera\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/validation-opera-linux.png\" alt=\"Screenshot of range field for Linux Opera\"><\/td>\n<\/tr>\n<tr>\n<th >IE8<br \/> (polyfill)<\/th>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Internet Explorer 6\" src=\"\/blog\/wp-content\/uploads\/2012\/03\/validation-ie8-windows.png\" alt=\"Screenshot of range field for Internet Explorer 6\"><\/td>\n<td colspan=\"2\" rowspan=\"2\">Not Applicable<\/td>\n<\/tr>\n<tr>\n<th >IE10<br \/> (native support)<\/th>\n<td >\n<img decoding=\"async\" title=\"Screenshot of range field for Internet Explorer 6\" src=\"\/blog\/wp-content\/uploads\/2012\/03\/validation-ie10-windows.png\" alt=\"Screenshot of range field for Internet Explorer 6\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>I especially found it interesting that Firefox changes the look of the bubbles to match the underlying operating system.   I can imagine that the graphic-designers out there reading this will probably want to control the look and feel of these bubbles.   <strong>It is possible to change the native style in Chrome<\/strong> using some Webkit-only CSS pseudo-classes, but currently <strong>it doesn&#8217;t look like we can style them in the other browsers that natively support HTML5 Forms<\/strong> (i.e. Firefox, Opera and IE10).  While I&#8217;m sure that these browsers will allow CSS styling of the bubbles in the near future, <strong>you can do it now by forcing webforms2 to render the bubbles instead of the native browser routines<\/strong> by setting <code>data-webforms2-force-js-validation=\"true\"<\/code> on the <code>form<\/code> tag (and the <code>script<\/code> tag that loads <code>html5Forms.js<\/code>).  Here is the code:<\/p>\n\r\n<blockquote class=\"code\">\r\n<pre>\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"&gt;\r\n&lt;head&gt;\r\n\r\n  &lt;script type=\"text\/javascript\" src=\"\/path\/to\/shared\/js\/modernizr.com\/Modernizr-2.5.3.forms.js\"&gt;\r\n  &lt;\/script&gt;\r\n\r\n  &lt;script <span class=\"hilite\">data-webforms2-force-js-validation=\"true\"<\/span>\r\n          data-webforms2-support=\"validation\" \r\n          src=\"\/path\/to\/html5Forms\/shared\/js\/html5Forms.js\" \r\n          type=\"text\/javascript\"&gt;\r\n  &lt;\/script&gt;\r\n&lt;\/head&gt;\r\n\r\n&lt;body&gt;\r\n  &lt;form <span class=\"hilite\">data-webforms2-force-js-validation=\"true\"<\/span> \r\n           id=\"styleBubbleExample\"\r\n           name=\"styleBubbleExample\"&gt;\r\n    &lt;table class=\"formTable\"&gt;\r\n      &lt;tr&gt;\r\n        &lt;th&gt;Full Name :&lt;\/th&gt;\r\n\r\n        &lt;td&gt;&lt;input type=\"text\" name=\"fullName\" value=\"\" required=\r\n        \"required\" placeholder=\"Required information\" \/&gt;&lt;\/td&gt;\r\n      &lt;\/tr&gt;\r\n\r\n      &lt;tr&gt;\r\n        &lt;th&gt;Company Name :&lt;\/th&gt;\r\n\r\n        &lt;td&gt;&lt;input type=\"text\" name=\"companyName\" required=\r\n        \"required\" value=\"\" placeholder=\r\n        \"Required information\" \/&gt;&lt;\/td&gt;\r\n      &lt;\/tr&gt;\r\n\r\n      &lt;tr&gt;\r\n        &lt;td&gt;&lt;\/td&gt;\r\n\r\n        &lt;td&gt;&lt;input type=\"submit\" value=\"Submit Information\" \/&gt;&lt;\/td&gt;\r\n      &lt;\/tr&gt;\r\n    &lt;\/table&gt;\r\n  &lt;\/form&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\r\n<\/blockquote>\r\n<p>Let&#8217;s say we wanted to change the balloons to be white with green text.  Here is the CSS:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n\/*\r\n *  STEP 1: change the bubble so background is white and text is green.\r\n *\/\r\n\r\n\/* Webkit *\/\r\ninput::-webkit-validation-bubble-message {\r\n\tcolor: green !important;\r\n\tbackground: white;\r\n\tborder: 1px solid black;\r\n\tpadding: 18px;\r\n\t\r\n}\r\n\r\n\/* Polyfill styles to do the same as above *\/\r\n.wf2_errorMsg {\r\n\tcolor: green !important;\r\n\tbackground: white;\r\n}\r\n\r\n\/* Removes the icon that appears in Webkit browsers by default *\/\r\ninput::-webkit-validation-bubble-icon {\r\n\tdisplay: none;\r\n}\r\n\r\n\/* Needed for IE to get rid of gradient background, or to replace it with another gradient *\/\r\n.wf2_errorMsg {\r\n\tfilter: none !important;\r\n}\r\n\r\n\r\n\/*\r\n * Step 2: The arrow\r\n *\/\r\n\r\ninput::-webkit-validation-bubble-arrow {\r\n    background: white;\r\n    border: solid black 1px;\r\n}\r\n\r\n\/* Polyfill *\/\r\n.wf2_errorMsg:before {\r\n    \/* By default, the image is 29x15, but you can change it and position it with CSS *\/\r\n    background: url('whiteValidationPointer.png') !important;\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>And here is the result:<\/p>\n<form action=\"https:\/\/www.useragentman.com\/testForm.php\" data-webforms2-force-js-validation=\"true\" id=\"styleBubbleExample\">\n<table class=\"formTable\" >\n<tr>\n<th>Full Name :<\/th>\n<td><input type=\"text\" name=\"fullName\" value=\"\" required=\"required\" placeholder=\"Required information\" \/><\/p>\n<div class=\"description\"><\/div>\n<\/td>\n<\/tr>\n<tr>\n<th>Company Name :<\/th>\n<td><input type=\"text\" name=\"companyName\" required=\"required\" value=\"\" placeholder=\"Required information\" \/><\/p>\n<div class=\"description\"><\/div>\n<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><input type=\"submit\" value=\"Submit Information\"\/><\/td>\n<\/tr>\n<\/table>\n<\/form>\n<p>Note that you could go even further and style the validation bubbles of individual form elements as well.  For example, let&#8217;s say you had two formfields, <code>fullName<\/code> and <code>companyName<\/code> and you wanted the error message for <code>fullName<\/code> to be green with a white background, and <code>companyName<\/code> to be have yellow text.  You could do so with the following CSS:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n\/*\r\n * Styling the \"Full Name\" error message.\r\n *\/\r\n\r\n\/*\r\n *  The background color of the main box \r\n *\/\r\n\r\n\/* Webkit *\/\r\ninput[name=\"fullName\"]::-webkit-validation-bubble-message {\r\n\tcolor: green !important;\r\n\tbackground: white;\r\n\tborder: 1px solid black;\r\n\tpadding: 18px;\r\n\t\r\n}\r\n\r\ninput[name=\"fullName\"]::-webkit-validation-bubble-icon {\r\n\tdisplay: none;\r\n}\r\n\r\n\/* Polyfill *\/\r\n#fullName_wf2_errorMsg {\r\n\tcolor: green !important;\r\n\tbackground: white;\r\n}\r\n\r\n\/* Needed for IE to get rid of gradient background, or to replace it with another gradient *\/\r\n#fullName_wf2_errorMsg .wf2_errorMsgContainer {\r\n\tfilter: none !important;\r\n}\r\n\r\n\r\n\/*\r\n * Step 2: The arrow\r\n *\/\r\n\r\n[name=\"fullName\"]::-webkit-validation-bubble-arrow {\r\n\tbackground: white;\r\n    border: solid black 1px;\r\n}\r\n\r\n\/* Polyfill *\/\r\n#fullName_wf2_errorMsg:before {\r\n\t\/* By default, the image is 29x15, but you can change it and position it with CSS *\/\r\n\tbackground: url('images\/whiteValidationPointer.png');\r\n}\r\n\r\n#companyName_wf2_errorMsg {\r\n\tcolor: yellow !important;\r\n}\r\n<\/pre>\n<\/blockquote>\n<p><a href=\"\/tests\/html5Forms\/tests\/html5Forms\/errorMessageStyling.html\" class=\"exampleLink\">See the above CSS in action<\/a><\/p>\n<h2>Using CSS to Show the Validity of Form Fields As The User Types<\/h2>\n<p>One of the coolest things you can do with CSS and HTML5 forms is to <strong>show the user the validity state of a form element as a user is typing.<\/strong>  Fill out the following form to see what I mean:<\/p>\n\r\n<form action=\"https:\/\/www.useragentman.com\/testForm.php\" id=\"validationCSSExample\">\r\n<table class=\"formTable testValidity\">\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Full Name :<\/th>\r\n\t\t\t\t\t<td><input type=\"text\" name=\"fullName\" value=\"\" required=\"required\" placeholder=\"Required information\" \/>\t\r\n\t\t\t\t\t<div class=\"description\"><\/div>\r\n\t\t\t\t\t<\/td>\r\n\t\t\t\t<\/tr>\r\n\t\t\t\t\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Zip Code :<\/th>\r\n\t\t\t\t\t<td><input type=\"text\" name=\"zipCode\" required=\"required\" pattern=\"[0-9]{5}(-?[0-9]{4})?\" value=\"\" placeholder=\"e.g. 90210\" \/>\r\n\t\t\t\t\t<div class=\"description\"><\/div>\r\n\t\t\t\t\t<\/td>\r\n\t\t\t\t<\/tr>\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td><\/td>\r\n\t\t\t\t\t<td><input type=\"submit\" value=\"Submit Information\"\/><\/td>\r\n\t\t\t\t<\/tr>\r\n\t\t\t<\/table>\r\n<\/form>\r\n<p>When the user focuses in on a particular form field, the required icon (<img decoding=\"async\" class=\"inline\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/asterisk_orange.png\" \/>) changes to an invalid icon (<img decoding=\"async\" class=\"inline\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/cancel.png\" \/>) until the user enters in a valid value, when the valid icon appears (<img decoding=\"async\" class=\"inline\" src=\"\/blog\/wp-content\/uploads\/2012\/04\/tick.png\" \/>).  This helps the user fill in the form correctly even before the submit button is pressed and will speed up form completion.  <\/p>\n<p>Here is the fully commented CSS that will show how we can implement this in all browsers (including the ones that use the webforms2 polyfill).<\/p>\n\r\n<blockquote class=\"code\">\r\n<pre>\r\n\/*\r\n * STEP 1: Show the user when a form field is required with an orange star.\r\n *\/\r\n\r\n\/* Browsers that implement HTML5 Forms Natively *\/\r\ninput:required, textarea:required{\r\n\tbackground:url(\"\/blog\/wp-content\/uploads\/2012\/04\/asterisk_orange.png\") no-repeat right top;\r\n}\r\n\r\n\/* Polyfill *\/\r\ninput[required] {\r\n\tbackground:url(\"\/blog\/wp-content\/uploads\/2012\/04\/asterisk_orange.png\") no-repeat right top;\r\n}\r\n\r\n\r\n\r\n\/*\r\n * STEP 2: Show the user when a form field has valid data in it with a green checkmark.\r\n *\/\r\n\r\n\/* Browsers that implement HTML5 Forms Natively *\/\r\ninput[required]:valid, textarea[required]:valid {\r\n\t\/* Make this important if you want IE10 to work right. *\/\r\n\tbackground:url(\"\/blog\/wp-content\/uploads\/2012\/04\/tick.png\") no-repeat right top !important;\r\n}\r\n\r\n\/* Polyfill *\/\r\ninput[required].wf2_valid {\r\n\tbackground:url(\"\/blog\/wp-content\/uploads\/2012\/04\/tick.png\") no-repeat right top;\r\n}\r\n\r\n\r\n\r\n\r\n\/*\r\n * STEP 3: Show the user when a form field has invalid data in it with a red 'X'.\r\n *\/\r\n\r\n\/* Browsers that implement HTML5 Forms Natively *\/\r\ninput:focus:invalid, textarea:focus:invalid {\r\n\tbackground:url(\"\/blog\/wp-content\/uploads\/2012\/04\/cancel.png\") no-repeat right top;\r\n}\r\n\r\n\/* Polyfill *\/\r\ninput.wf2_invalid:focus {\r\n\tbackground:url(\"\/blog\/wp-content\/uploads\/2012\/04\/cancel.png\") no-repeat right top;\r\n}\r\n\r\n<\/pre>\r\n<\/blockquote>\r\n<h2>Customizing the Error Messages<\/h2>\n<p>Note that the <strong>default error messages may vary<\/strong> from browser to browser:<\/p>\n<table class=\"dataTable screenshots minimalWidth\">\n<thead>\n<tr>\n<th>Opera Mac<\/th>\n<th>Firefox Mac<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2012\/03\/validation-firefox4-mac.png\" \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2012\/04\/validation-opera-mac.png\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>This may not be a big deal the majority of time, but there will be some cases where you want have more control over the error messages.  Although this can be done via JavaScript using a form element&#8217;s <code>setCustomValidity()<\/code> method, Firefox has an attribute, <code>x-moz-errormessage<\/code> which can be used to set custom error messages easily.  I really liked this idea, so I thought it would be cool to implement a dataset attribute for HTML5Forms.js, <code>data-errormessage<\/code>, that would do the same thing:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;input type=\"text\" name=\"zipc\" required=\"required\" pattern=\"[0-9]{5}(-?[0-9]{4})?\"\r\n        placeholder=\"Required information\"\r\n        <span class=\"hilite\">data-errormessage=\"You must enter a valid Zip Code (e.g. 90210)\"<\/span> \/&gt;\r\n<\/pre>\n<\/blockquote>\n<p>Below is a great example of this attribute in action:<\/p>\n\r\n<form action=\"https:\/\/www.useragentman.com\/testForm.php\">\r\n<table class=\"formTable\">\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<th>Zip Code :<\/th>\r\n\t\t\t\t\t<td><input type=\"text\" name=\"zipc\" value=\"\" required=\"required\" placeholder=\"Required information\" pattern=\"[0-9]{5}(-?[0-9]{4})?\"\r\n\t\t\tdata-errormessage=\"You must enter a valid Zip Code (e.g. 90210)\"\r\n                                                \/>\r\n\t\t\t\t\t<div class=\"description\"><\/div>\r\n\t\t\t\t\t<\/td>\r\n\t\t\t\t<\/tr>\r\n\r\n\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t<tr>\r\n\t\t\t\t\t<td><\/td>\r\n\t\t\t\t\t<td><input type=\"submit\" value=\"Submit Information\"\/><\/td>\r\n\t\t\t\t<\/tr>\r\n\t\t\t<\/table>\r\n<\/form>\r\n<h2>Conclusion<\/h2>\n<p>Validation support for HTML5 Forms in the various browsers is still spotty, but HTML5Forms.js can help if you want to do it now.  I have used it myself in a few professional projects and I hope you find out of use too.   <\/p>\n<h2>Footnotes<\/h2>\n<p><a href=\"#top\">^<\/a>  <a name=\"foot1\" id=\"foot1\"><sup>1<\/sup><\/a> Note that Safari and some older versions of Chrome natively support the validation CSS part of the HTML5 Forms specification, but don&#8217;t display the error message bubbles.  I believe that this is due to the version of Webkit that is being used for these browsers (v. 533 and lower).  With HTML5Forms.js, though, allows you not to worry about such problems.  :-)<\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2012\/05\/promo.png\">I have updated my html5Widgets package (now called <strong>html5Forms.js<\/strong>) so developers can create <strong>great looking, easy-to-use forms that can validate each field as a user types<\/strong>.  It also has <strong>updated validation widgets<\/strong> so older browsers can display error messages like native HTML5 Form implementations do, and even allows developers to <strong>style error message bubbles in all browsers<\/strong> even in browsers like Firefox that don&#8217;t allow it natively.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38,50,35,1],"tags":[],"class_list":["post-4472","post","type-post","status-publish","format-standard","hentry","category-css3","category-forms","category-html5","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/4472","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/comments?post=4472"}],"version-history":[{"count":264,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/4472\/revisions"}],"predecessor-version":[{"id":5606,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/4472\/revisions\/5606"}],"wp:attachment":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/media?parent=4472"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/categories?post=4472"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/tags?post=4472"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}