{"id":621,"date":"2010-11-29T11:06:27","date_gmt":"2010-11-29T17:06:27","guid":{"rendered":"http:\/\/cssnewbie.com\/?p=621"},"modified":"2010-11-29T11:06:27","modified_gmt":"2010-11-29T17:06:27","slug":"cross-browser-support-for-html5-placeholder-text-in-forms","status":"publish","type":"post","link":"https:\/\/cssdeck.com\/blog\/cross-browser-support-for-html5-placeholder-text-in-forms\/","title":{"rendered":"Cross-Browser Support for HTML5 Placeholder Text in Forms"},"content":{"rendered":"<p><a href=\"http:\/\/cssnewbie.com\/example\/placeholder-support\/\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2010\/11\/placeholder-beauty-shot.png\" alt=\"\" title=\"Placeholder text in action\" width=\"500\" height=\"120\" class=\"alignnone size-full wp-image-622\" \/><\/a><\/p>\n<p>HTML5 offers a lot of exciting new features in the realm of forms. One of my favorite new additions to forms in HTML5 is the placeholder attribute. Placeholder text is the \u201chint&#8221; or \u201cexample&#8221; text that resides in a text input field before the user clicks in (or tabs to) that field &mdash; and goes away the moment the field is in use. And the code is amazingly simple, too. Take this example:<\/p>\n<pre lang=\"html4strict\" escaped=\"true\"> &lt;input type=&quot;text&quot; placeholder=&quot;Start typing to begin searching.&quot; \/&gt;<\/pre>\n<p>The only new bit is the placeholder attribute, but it results in this:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2010\/11\/placeholder-example-image-1.png\" alt=\"\" title=\"Placeholder text example\" width=\"500\" height=\"60\" class=\"alignnone size-full wp-image-623\" \/><\/p>\n<p>I love placeholder text because it can help make large, complex forms easier to navigate. What better place to explain the requirements of an input field than right inside the field itself? And on short forms (like a search bar), placeholder text could be used instead of a field label, making your form that much more compact (though the W3C still suggests you use a label field).<\/p>\n<p>The only real downside to placeholder text, as I see it, is I can\u2019t use it <strong>right now<\/strong> \u2026 or at least, it won\u2019t show up everywhere. <!--more--> Placeholder text is supported by Firefox 3.7+ and Chrome\/Safari 4.0+, but Opera is late to the party and Internet Explorer is, as usual, conspicuously absent. The good news is those browsers won\u2019t break if they encounter a placeholder attribute: they\u2019ll just ignore it entirely. But if you were planning to use placeholders to relay important information to your users, that omission might be enough to make you call the whole thing off.<\/p>\n<p>I\u2019m a notoriously impatient person, and I don\u2019t like to miss out on cool new functionality just because Aunt Gertrude can\u2019t be convinced to switch away from Internet Explorer. So I suggest this as a workaround for the time being: <strong>let\u2019s use placeholder text NOW, for all browsers that support it, and fake the same functionality for legacy browsers.<\/strong><\/p>\n<h3>Use Placeholder Text Now<\/h3>\n<p>This is the easy part. For modern browsers, all we have to do is start using the placeholder attribute, and everything will work automatically. So this:<\/p>\n<pre lang=\"html4strict\" escaped=\"true\"> &lt;input type=&quot;text&quot; placeholder=&quot;Start typing to begin searching.&quot; \/&gt;<\/pre>\n<p>Becomes this:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2010\/11\/placeholder-example-image-1.png\" alt=\"\" title=\"Placeholder text example\" width=\"500\" height=\"60\" class=\"alignnone size-full wp-image-623\" \/><\/p>\n<p>Easy as pie.<\/p>\n<h3>All Browsers That Support It<\/h3>\n<p>As I said earlier, as of the time of this writing, placeholder text is supported by Firefox 3.7+ and Chrome\/Safari 4.0+. However, this will inevitably change over time, so we shouldn\u2019t rely on these data to make our implementation decisions. Besides, browser sniffing is SO 20th century. Instead, we\u2019ll write a bit of jQuery to find out whether the user\u2019s browser supports the placeholder attribute. This way, as soon as IE or Opera decide to come join the fun, placeholders on your site will just magically work without any additional help from us.<\/p>\n<p>This code will do the trick:<\/p>\n<pre lang=\"javascript\" escaped=\"true\"> jQuery(function() {\n\tjQuery.support.placeholder = false;\n\ttest = document.createElement('input');\n\tif('placeholder' in test) jQuery.support.placeholder = true;\n});<\/pre>\n<p>What I\u2019m doing here is extending the jQuery.support object, just like we did when <a href=\"http:\/\/cssnewbie.com\/test-for-border-radius-support\/\">we tested for border-radius support.<\/a> I\u2019m using JavaScript to create a new input object, and then I\u2019m testing to see if the \u201cplaceholder&#8221; attribute is an option inside that object. It will be an option in browsers that support placeholder text, and absent in those that don\u2019t.<\/p>\n<p>Once we\u2019ve run that code, we\u2019ll be able to check against the jQuery.support object, like so:<\/p>\n<pre lang=\"javascript\" escaped=\"true\"> if(!$.support.placeholder) {\n\/\/ Placeholder text is not supported. \n}<\/pre>\n<h3>Fake the Same Functionality<\/h3>\n<p>So now we just need to get the other browsers to behave the same way. And I discovered something that will make our job easier: even if the user\u2019s browser doesn\u2019t recognize the placeholder attribute, <em>the jQuery running inside that browser will still find it just fine!<\/em> So we can use the placeholder element in our jQuery. This means we don\u2019t have to do anything fancy to the input element to make it work.<\/p>\n<p>The following code looks a little complicated (and it is, logic-wise), but it does the trick.<\/p>\n<pre lang=\"javascript\" escaped=\"true\"> $(function() {\n\tif(!$.support.placeholder) { \n\t\tvar active = document.activeElement;\n\t\t$(':text').focus(function () {\n\t\t\tif ($(this).attr('placeholder') != '' &amp;&amp; $(this).val() == $(this).attr('placeholder')) {\n\t\t\t\t$(this).val('').removeClass('hasPlaceholder');\n\t\t\t}\n\t\t}).blur(function () {\n\t\t\tif ($(this).attr('placeholder') != '' &amp;&amp; ($(this).val() == '' || $(this).val() == $(this).attr('placeholder'))) {\n\t\t\t\t$(this).val($(this).attr('placeholder')).addClass('hasPlaceholder');\n\t\t\t}\n\t\t});\n\t\t$(':text').blur();\n\t\t$(active).focus();\n\t\t$('form').submit(function () {\n\t\t\t$(this).find('.hasPlaceholder').each(function() { $(this).val(''); });\n\t\t});\n\t}\n});<\/pre>\n<p>The first thing we\u2019re doing is finding out if there\u2019s a form element currently selected (which would be automatically selected when the page loads). If so, we store it in the \u201cactive&#8221; variable, so we can set it special later. Next, we create two event functions for our elements (I\u2019m targeting \u201ctext&#8221; inputs, but you could expand\/contract this as you need): a focus function (for when the element gets clicked in\/tabbed to) and a blur element (for when the user goes elsewhere). <\/p>\n<p>The blur function first checks to see if the input element has a placeholder set, and if it does, if the value of the input\u2019s value is either blank (the user didn\u2019t enter anything before moving on) or if it\u2019s the same as the placeholder text. If so, we know that we\u2019re supposed to be applying a placeholder on blur. So we set the value (content) of the input to be the same as the placeholder text, and we add a class of \u201chasPlaceholder&#8221; to the input so we can style it to look like placeholder text. <\/p>\n<p>The focus function first checks to see if the element has a placeholder set, and if it does, if the current \u201cvalue&#8221; of the input area is the same as the placeholder text. If so, that means that the user just clicked into an input field that has our fake placeholder applied. So we blank out the input\u2019s value field and remove the \u201chasPlaceholder&#8221; class. <\/p>\n<p>Then we do a few more housekeeping things.  We\u2019re running the \u201cblur&#8221; function on all our fields when the page loads, which adds placeholders wherever they need to be. We then re-focus the originally active field, which would remove the placeholder from that particular field and move the cursor there. And we have a final function that fires on form submission, which strips out the value fields of any fields that have the \u201chasPlaceholder&#8221; class applied. This prevents us from accidentally sending along our faked placeholder copy as an actual user input.<\/p>\n<p>And how do we style our input\u2019s new faked placeholder copy to make it look like a real placeholder? It turns out that placeholder styling isn\u2019t that complicated on average, so it doesn\u2019t take much work:<\/p>\n<pre lang=\"css\"> .hasPlaceholder {\n\tcolor: #777;\n}<\/pre>\n<p>And with that, you have placeholders that work in ALL modern browsers, not just the fancy ones! <a href=\"http:\/\/cssnewbie.com\/example\/placeholder-support\/\">You can see a demo here. Give it a try in various browsers.<\/a> <\/p>\n<div class=\"wp-socializer wpsr-share-icons \" data-lg-action=\"show\" data-sm-action=\"show\" data-sm-width=\"768\" ><h3>Share and Enjoy !<\/h3><div class=\"wpsr-si-inner\"><div class=\"wpsr-counter wpsrc-sz-32px\" style=\"color:#000\"><span class=\"scount\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook,twitter,linkedin,pinterest,print,pdf\">0<\/span><\/span><small class=\"stext\">Shares<\/small><\/div><div class=\"socializer sr-popup sr-32px sr-circle sr-opacity sr-pad sr-count-1 sr-count-1\"><span class=\"sr-facebook\"><a rel=\"nofollow\" href=\"https:\/\/www.facebook.com\/share.php?u=\" target=\"_blank\"  title=\"Share this on Facebook\"  style=\"color: #ffffff\" ><i class=\"fab fa-facebook-f\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-twitter\"><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/intent\/tweet?text=%20-%20%20\" target=\"_blank\"  title=\"Tweet this !\"  style=\"color: #ffffff\" ><i class=\"fab fa-twitter\"><\/i><\/a><\/span>\n<span class=\"sr-linkedin\"><a rel=\"nofollow\" href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=\" target=\"_blank\"  title=\"Add this to LinkedIn\"  style=\"color: #ffffff\" ><i class=\"fab fa-linkedin-in\"><\/i><\/a><\/span>\n<span class=\"sr-pinterest\"><a rel=\"nofollow\" href=\"https:\/\/www.pinterest.com\/pin\/create\/button\/?url=&amp;media=&amp;description=\" target=\"_blank\"  title=\"Submit this to Pinterest\"  style=\"color: #ffffff\" data-pin-custom=\"true\"><i class=\"fab fa-pinterest\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"pinterest\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-print\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Print this article \"  style=\"color: #ffffff\" ><i class=\"fa fa-print\"><\/i><\/a><\/span>\n<span class=\"sr-pdf\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Convert to PDF\"  style=\"color: #ffffff\" ><i class=\"fa fa-file-pdf\"><\/i><\/a><\/span><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>One of my favorite new additions to forms in HTML5 is the placeholder attribute. I love placeholder text because it can help make large, complex forms easier to navigate. Unfortunately, not every modern browser supports it yet. But I say, let\u2019s use placeholder text NOW, for all browsers that support it, and fake the same functionality for legacy browsers. [&#8230;]<\/p>\n<p><a class=\"more-link article\" href=\"https:\/\/cssdeck.com\/blog\/cross-browser-support-for-html5-placeholder-text-in-forms\/\" title=\"Click to read 'Cross-Browser Support for HTML5 Placeholder Text in Forms'\">Read Article<\/a><\/p>\n","protected":false},"author":18,"featured_media":622,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[165,181],"tags":[],"_links":{"self":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/621"}],"collection":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/comments?post=621"}],"version-history":[{"count":0,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/621\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media\/622"}],"wp:attachment":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media?parent=621"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/categories?post=621"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/tags?post=621"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}