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 “hint” or “example” text that resides in a text input field before the user clicks in (or tabs to) that field — and goes away the moment the field is in use. And the code is amazingly simple, too. Take this example:
<input type="text" placeholder="Start typing to begin searching." /> |
The only new bit is the placeholder attribute, but it results in this:

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).
The only real downside to placeholder text, as I see it, is I can’t use it right now … or at least, it won’t show up everywhere. 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’t break if they encounter a placeholder attribute: they’ll 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.
I’m a notoriously impatient person, and I don’t like to miss out on cool new functionality just because Aunt Gertrude can’t be convinced to switch away from Internet Explorer. So I suggest this as a workaround for the time being: let’s use placeholder text NOW, for all browsers that support it, and fake the same functionality for legacy browsers.
Use Placeholder Text Now
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:
<input type="text" placeholder="Start typing to begin searching." /> |
Becomes this:

Easy as pie.
All Browsers That Support It
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’t rely on these data to make our implementation decisions. Besides, browser sniffing is SO 20th century. Instead, we’ll write a bit of jQuery to find out whether the user’s 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.
This code will do the trick:
jQuery(function() { jQuery.support.placeholder = false; test = document.createElement('input'); if('placeholder' in test) jQuery.support.placeholder = true; }); |
What I’m doing here is extending the jQuery.support object, just like we did when we tested for border-radius support. I’m using JavaScript to create a new input object, and then I’m testing to see if the “placeholder” attribute is an option inside that object. It will be an option in browsers that support placeholder text, and absent in those that don’t.
Once we’ve run that code, we’ll be able to check against the jQuery.support object, like so:
if(!$.support.placeholder) { // Placeholder text is not supported. } |
Fake the Same Functionality
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’s browser doesn’t recognize the placeholder attribute, the jQuery running inside that browser will still find it just fine! So we can use the placeholder element in our jQuery. This means we don’t have to do anything fancy to the input element to make it work.
The following code looks a little complicated (and it is, logic-wise), but it does the trick.
$(function() { if(!$.support.placeholder) { var active = document.activeElement; $(':text').focus(function () { if ($(this).attr('placeholder') != '' && $(this).val() == $(this).attr('placeholder')) { $(this).val('').removeClass('hasPlaceholder'); } }).blur(function () { if ($(this).attr('placeholder') != '' && ($(this).val() == '' || $(this).val() == $(this).attr('placeholder'))) { $(this).val($(this).attr('placeholder')).addClass('hasPlaceholder'); } }); $(':text').blur(); $(active).focus(); $('form').submit(function () { $(this).find('.hasPlaceholder').each(function() { $(this).val(''); }); }); } }); |
The first thing we’re doing is finding out if there’s a form element currently selected (which would be automatically selected when the page loads). If so, we store it in the “active” variable, so we can set it special later. Next, we create two event functions for our elements (I’m targeting “text” 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).
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’s value is either blank (the user didn’t enter anything before moving on) or if it’s the same as the placeholder text. If so, we know that we’re 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 “hasPlaceholder” to the input so we can style it to look like placeholder text.
The focus function first checks to see if the element has a placeholder set, and if it does, if the current “value” 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’s value field and remove the “hasPlaceholder” class.
Then we do a few more housekeeping things. We’re running the “blur” 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 “hasPlaceholder” class applied. This prevents us from accidentally sending along our faked placeholder copy as an actual user input.
And how do we style our input’s new faked placeholder copy to make it look like a real placeholder? It turns out that placeholder styling isn’t that complicated on average, so it doesn’t take much work:
.hasPlaceholder { color: #777; } |
And with that, you have placeholders that work in ALL modern browsers, not just the fancy ones! You can see a demo here. Give it a try in various browsers.

It’s not working for me on IE9
Any idea for Opera Mini browser. It still didn’t work.
I m using opera mini 7.0.1
Howdy! I’m at work browsing your blog from my new iphone! Just wanted to say I love reading through your blog and look forward to all your posts! Keep up the fantastic work!
helped me a lot thank you congratulations on the blog post
Works very well in IE versions. But not work with fields that uses mask like maskedInput http://digitalbush.com/projects/masked-input-plugin/
Shouldn’t this code
jQuery(function() {
jQuery.support.placeholder = false;
test = document.createElement(‘input’);
if(‘placeholder’ in test) jQuery.support.placeholder = true;
});
really be
jQuery(function() {
test = document.createElement(‘input’);
jQuery.support.placeholder = (‘placeholder’ in test);
});
I have had an issue with this technique in IE: in the “blur” event the if sentence is:
if ($(this).attr(‘placeholder’) != ” && ($(this).val() == ” || $(this).val() == $(this).attr(‘placeholder’)))
In my code it always passed the condition, as $(this).attr(‘placeholder’) returned “undefined” instead of “” in IE. As a result of this, field values posted empty :( So i inserted additional cond:
if (typeof($(this).attr(‘placeholder’)) !== “undefined” && $(this).attr(‘placeholder’) != ” && ($(this).val() == ” || $(this).val() == $(this).attr(‘placeholder’))) {…}
Hi, I wish for to subscribe for this webpage to get most
recent updates, thus where can i do it please assist.
I’ll immediately snatch your rss feed as I can’t in finding your e-mail subscription hyperlink or newsletter
service. Do you have any? Kindly allow me understand so that I may
just subscribe. Thanks.
I’m impressed, I must say. Rarely do I come across a blog that’s equally educative and engaging, and let me tell you,
you have hit the nail on the head. The issue is an issue that not enough men and women are speaking intelligently about.
I am very happy I came across this in my hunt
for something regarding this.
If you are going for best contents like me, simply visit this website every day since
it provides quality contents, thanks
Wonderful site. A lot of helpful info here. I am sending it to some friends ans additionally sharing in delicious.
And naturally, thank you in your effort!
Wow that was unusual. I just wrote an very long comment but after I clicked
submit my comment didn’t appear. Grrrr… well I’m not writing all that over again.
Anyhow, just wanted to say superb blog!
Brilliant, thanks so much for this post – sorted me right out :)
Hi there, I desire to subscribe for this webpage to get latest updates, therefore
where can i do it please assist.
I tried this fix and many other but, for some reason none of them worked for me. I wrote a fix of my own if anyone else needs it: http://www.sciencestudioz.com/input-element-placeholder-attribute-in-ie
Write more, thats all I have to say. Literally, it seems as though you relied on the
video to make your point. You clearly know what youre talking about,
why throw away your intelligence on just posting
videos to your site when you could be giving us something informative to read?
My spouse and I stumbled over here coming from a different web address and thought I should check things out.
I like what I see so i am just following you.
Look forward to looking at your web page again.
It’s arduous to discover educated people just for this subject,
however you seem to be you realize what you’re talking about!
Thanks
Works fine, even on WordPress.
Thanks a lot ;)
If some one wants to be updated with most up-to-date
technologies afterward he must be pay a quick visit this website and be up to date all the time.
Exceptional post however , I was wondering if you could write a litte more on this topic?
I’d be very grateful if you could elaborate a little bit more. Many thanks!
Im no jQuery expoert but when i add this to the if(!$.support.placeholder) it works for the password field
$(‘input:password’).val(‘Password’); jQuery(‘form’).find(‘input:password’).focus(function() {
if (this.value == ‘Password’){
this.value = ”;
}
if(this.value != this.defaultValue){
this.select();
}
});
jQuery(‘form’).find(‘input:password’).blur(function() {
if (jQuery.trim(this.value) == ”){
this.value = ‘Password’;
}
});
Hello! firstly I’m sorry for my english because I’m talking french.My name is Sofyan and I am very happy to discover your website.I am a beginner developer and I find your alternative to make a placeholder very nice.Respect from Morrocco.
If you need something here is my email : perso_8@hotmail.com
I’m using this solution for a site that loads (shows) a form with ajax and it doesn’t show the placeholder in IE
HELP!
Thanks a lot, works perfectly even in IE8.
On my page I altered it to also use inputs of the type “email”:
$("[type='text'], [type='email']").Thanks a lot.You save me.:)
Great bit of code…exactly what I was looking for.
Oliver’s change above fixes it in IE9 for me.
One other suggestion. You blur all the fields on load to get the hints showing, then have to go refocus on the originally active element. It would be a lot simpler and cleaner to simply trigger the hints to show without focusing or blurring anything, which you can do by creating and firing a custom ‘load’ event. So instead of this:
var active = document.activeElement;$(':text').focus(function() {
if ($(this).attr('placeholder') != '' && $(this).val() == $(this).attr('placeholder')) {
$(this).val('').removeClass('hasPlaceholder');
}
}).blur(function() {
if ($(this).attr('placeholder') != '' && ($(this).val() == '' || $(this).val() == $(this).attr('placeholder'))) {
$(this).val($(this).attr('placeholder')).addClass('hasPlaceholder');
}
});
$(':text').blur();
$(active).focus();
you can simply do this:
$(':text').focus(function() {
if ($(this).attr('placeholder') != '' && $(this).val() == $(this).attr('placeholder')) {
$(this).val('').removeClass('hasPlaceholder');
}
}).bind('load blur', function() {
if ($(this).attr('placeholder') != '' && ($(this).val() == '' || $(this).val() == $(this).attr('placeholder'))) {
$(this).val($(this).attr('placeholder')).addClass('hasPlaceholder');
}
}).trigger('load');
Here’s that last bit of code again, since your CSS is making <code> blocks unreadable.
$(‘:text’).focus(function() {
if ($(this).attr(‘placeholder’) != ” && $(this).val() == $(this).attr(‘placeholder’)) {
$(this).val(”).removeClass(‘hasPlaceholder’);
}
}).bind(‘load blur’, function() {
if ($(this).attr(‘placeholder’) != ” && ($(this).val() == ” || $(this).val() == $(this).attr(‘placeholder’))) {
$(this).val($(this).attr(‘placeholder’)).addClass(‘hasPlaceholder’);
}
}).trigger(‘load’);
Also, I’ve never liked that, in most browsers that support placeholder text, the placeholder stays in the fields on focus and doesn’t go away until you enter something. I prefer it to disappear on focus, which is the same behavior as the function above sets up.
It’s easy enough to modify the function above to do this–cause browsers that do support placeholder text to make it disappear on focus. Just add this “else” block at the end, just inside the final brackets:
} else {
$(‘:text[placeholder]‘).each(function() {
$(this).attr(‘oPlaceholder’,$(this).attr(‘placeholder’));
}).focus(function() {
$(this).attr(‘placeholder’,”);
}).blur(function() {
$(this).attr(‘placeholder’,$(this).attr(‘oPlaceholder’));
}).trigger(‘load’);
}
Here’s more efficient version of Cameron code:
$(function() {
var active = document.activeElement;
var inputs = $(‘:text[placeholder]‘);
if(Modernizr.input.placeholder){
inputs.each(function()
{
var self = $(this);
self.data(‘oPlaceholder’,self.attr(‘placeholder’));
}).focus(function()
{
$(this).attr(‘placeholder’,”);
}).blur(function()
{
var self = $(this);
self.attr(‘placeholder’,self.data(‘oPlaceholder’));
}).trigger(‘load’);
return false;
} else {
inputs.focus(function()
{
var self = $(this);
if (self.attr(‘placeholder’) != ” && self.val() == self.attr(‘placeholder’)) {
self.val(”).removeClass(‘placeholder’);
}
}).on(‘load blur’, function()
{
var self = $(this);
if (self.attr(‘placeholder’) != ” && (self.val() == ” || self.val() == self.attr(‘placeholder’))) {
self.val(self.attr(‘placeholder’)).addClass(‘placeholder’);
}
}).trigger(‘load’);
inputs.blur();
$(active).focus();
$(‘form’).submit(function () {
var self = $(this);
self.find(‘.placeholder’).each(function() { self.val(”); });
});
}
return true;
});
Hello, i think that i saw you visiteԁ my website so
i came to “return the favor”.Ι’m attempting to find things to enhance my website!I suppose its ok to use a few of your ideas!!
mail order bride cost
If you want it to also work with TEXTAREA, as I did. Just make a duplicate and replace all the ‘:text’ with ‘textarea’ and all the ‘.val()’ with ‘.html()’.
Thanks for the script!
Rob, you are my hero. Thank you for this article :))
IE stinks
This works perfectly with my website too.
Great! This works just fine. If you copy the code into your HTML head section don’t forget to wrap it in script tags and include the jQuery library.
It works fine on my wordpress site. Thanks a lot
This is a great fix, very quick to implement with little knowledge of jQuery too. Thank you for sharing it!