Jack MooreTwitterGithub

HTML5 Placeholder Attribute


Nov 8th, 2011  »  9 comments

A guide to using the attribute, and support it for older browsers.


Placeholder

Placeholder text is a short example or hint text that is shown in a form field when the field is unfocused and has no input from the user. Designers like to use placeholders to make forms smaller, as smaller things appear to be simpler.




While the adding & removing of placeholder text on field focus has long been accomplished through JavaScript, there is now a placeholder attribute in the HTML5 working draft. Most modern browsers support the placeholder attribute and will automatically add/replace the placeholder text. They will also automatically exclude the placeholder from being sent when the form is submitted. However, versions of Internet Explorer prior to IE10 do not support the attribute.

<input type='text' name='email' placeholder='Email Address'/>

Supporting Older Browsers

It is very easy to detect placeholder support (or lack of) and duplicate the effect with a bit of JavaScript for older browsers.

<script>
    // placeholder polyfill
    $(document).ready(function(){
        function add() {
            if($(this).val() == ''){
                $(this).val($(this).attr('placeholder')).addClass('placeholder');
            }
        }

        function remove() {
            if($(this).val() == $(this).attr('placeholder')){
                $(this).val('').removeClass('placeholder');
            }
        }

        // Create a dummy element for feature detection
        if (!('placeholder' in $('<input>')[0])) {

            // Select the elements that have a placeholder attribute
            $('input[placeholder], textarea[placeholder]').blur(add).focus(remove).each(add);

            // Remove the placeholder text before the form is submitted
            $('form').submit(function(){
                $(this).find('input[placeholder], textarea[placeholder]').each(remove);
            });
        }
    });
</script>

To enable styling, this script adds a class of 'placeholder' while the placeholder text is being displayed.

Styling The Placeholder

Since placeholder has yet to be standardized, styles are applied through vendor-specific prefixes. Even though Opera 11 supports the placeholder attribute, it does not offer any way to style it at this time. It's a good idea to go ahead and specify at least the color property to normalize the color between browsers. Otherwise, a default style will be provided which will vary from browser to browser.

::-webkit-input-placeholder { color:#999; }
:-moz-placeholder { color:#999; }
:-ms-input-placeholder { color:#999; }
.placeholder { color:#999; }

Unfortunately, the rules can not be combined into a single statement as a browser will not recognize vendor-specific selectors from other browser makers, resulting in an invalid rule that prevents the styles from being applied. John Catterfeld compiled a nifty list of CSS properties can be applied to placeholders.


Hey You

Follow me on Twitter, Github, or RSS. Why should you? I'm meticulous and have a lot of free time. Sometimes good things come out of that.

Comments

michael6 months agoReply
No need to self-close the <input> tag - this is HTML5, not XHTML5 :-)
Anonymous6 months agoReply
To be honest, I like self closing tags as a note that I do not need to match it when cleaning up.
Jack6 months agoReply
Michael is right of course, but since both are valid I appreciate the explicitness of the self-closing tag. It makes it very clear that there is no closing tag, and the omission of a closing tag is not a mistake. I don't know if that is a good enough reason use them still, I may be stuck in the mindset after years of using XHTML.
Adam6 months agoReply
I like the tag and hate to come to just complain but the only problem here I can see is that your checker to see if the placeholder exists takes up more space than a javascript swap function for onfocus / onblur using a superfluous field like longdesc.
//Bind these by hardcoding them or if you're using JQuery do something fancy
function SwapOnFocus(obj) {
    if (obj.value == obj.title) {
        obj.value = '';
        obj.class = 'active'; /* JQuery has really nice class swaps or you could define a var baseInputClass and add to that here */
    }
}

function SwapOnBlur(obj) {
    if (obj.value == obj.title || obj.value == '') {
        obj.value = obj.title;
        obj.class = '';
    }
}
I always try to use the placeholder for example text instead of field names: http://mediamanifesto.com
Jack6 months agoReply
You would still have to bind your swap functions to the elements (and hopefully just to the ones that need it), and you should still remove them from form submissions (I can't imagine the placeholder text being submitted as being the desired behavior). So the only functional difference between the scripts is this:
if (!('placeholder' in $('<input>')[0]))
I think that is a more than fair trade-off in order to be able to use browser-native placeholder swapping in supported browsers. However, my script could be written more tersely to save bytes, such as replacing the 'placeholder' string with a variable.
Kevin McGee6 months agoReply
Jack, *Great* script; absolutely what I was looking for and it performs beautifully. Thanks so much for contributing your work. An oddity I have seen on my project that I wanted to share. To get my copy of IE9 to observe the '.placeholder' class I must keep it 'local' in the actual HTML that's rendered. Moving it to a style sheet kills it. The CSS rules I have against the input field take precedence so I suspect a hierarchy problem, but - wait for it - "it only happens in IE". Have you ever heard of anything such as this? Regards.. and thanks again.
Jack5 months agoReply
Hey Kevin, sorry about the late reply. IE9 didn't give me any trouble with the class when I was putting this together, but you are probably right that it's a specificity problem. Once way you could raise the specificity is by prepending the class with the tag name, ie:
input.placeholder, textarea.placeholder{ color:#999; }
Since classes (.placeholder) and pseudo-classes (:-ms-input-placeholder) have the same specificity level, you would expect the same results in IE8 (or lower) as you would get in other browsers. However, I believe the placeholder pseudo-class applies style to the placeholder text node instead of the input element. This gives styles applied with the pseudo-class a much higher specificity than a style applied through a class on the input element. Styles applied to the input element through a class selector are treated by the placeholder text node the same as styles inherited from a parent element. That is just my impression of what is happening here, I would love for someone to explain just how I mutilated that explaination.
Kevin McGee5 months agoReply
Nice work, Jack. The increase of specificity you suggested seems to have done the trick. I'm going to watch the behavior of our project in a few browsers for awhile, but initial testing looks great. Best, Kevin M.
Anonymousa month agoReply
Hey what about password fields? They aren't show very well ;) Maybe a little snippet for that?

Leave a Comment