Placeholder Polyfill with Password Support

I use input placeholders in two ways: (1) as labels in simple forms that have just a few input fields and (2) as tips or suggestions in complex forms:

<input type="email" name="email" placeholder="Your email address" />

Placeholder Polyfill with Password Support

The problem with placeholders is that the feature is not supported in IE 9 and below. This is a huge pain if you use placeholders as labels…

JavaScript polyfill

​I have written a tiny jQuery-dependent plugin which enables placeholders in browsers that do not support the technology:

  1. jquery.input-placeholder-polyfill.js (uncompressed; 2 KB);
  2. jquery.input-placeholder-polyfill.min.js (minified; 966 bytes).

Basic usage example:

<script src="jquery.js"></script>
<script src="jquery.input-placeholder-polyfill.js"></script>
<script>
	;(function($, window, document, undefined) {
		$('input').inputPlaceholderPolyfill();
	}
	)(jQuery, window, document);
</script>

Or you can target input fields by a specific selector:

$('.textfield').inputPlaceholderPolyfill();

The plugin takes care of textareas and text-oriented inputs, including password type. Some other polyfills I have tried before had this bug, when you entered the text which was equal to input‘s placeholder value the input automatically cleared out, became blank. This is fixed in my version.

How the plugin works? Firstly, it detects if the browser does not support input placeholders. Then if the [placeholder] of <input /> has a non-empty value, the plugin sets the same value for [value] attribute and adds a class name for the input (is-placeholder by default). The plugin also makes various checks and actions on input focus, blur and form submit events to keep the values of [placeholder] and [value] correct.

What is the is-placeholder class name for? Firstly, it‘s for styling the input when it has a placeholder mode enabled. Just one additional line next to the styles for native placeholder:

.textfield.is-placeholder             { color: grey !important; }
.textfield::-webkit-input-placeholder { color: grey !important; }
.textfield::-moz-placeholder          { color: grey !important; }
.textfield:-ms-input-placeholder      { color: grey !important; }

Secondly, it‘s for managing the input via JavaScript. The classic example is validating input values. Since the plugin uses [value] for placeholder text, you have to make sure you are validating the actual value (the one that user enters), not the placeholder text:

$('form').on('submit', function(e) {
	e.preventDefault();

	$(this).find('.textfield').each(function() {
		var $this = $(this),
		    val = $this.val();

		if($this.hasClass('is-placeholder'))
			val = '';
		// ...
	});
	// ...
});

If you need, you can have a custom class name:

$('.textfield').inputPlaceholderPolyfill({
	className: 'textfield--placeholder'
});

But… what about browsers that do not support placeholders and has JavaScript disabled?

CSS fallback

You can use a combination of both: JavaScript polyfill and CSS fallback for it, or you can bypass the JavaScript part and completely rely on CSS fallback. Or vice versa. Your situation dictates what you should do. In the end, the user should be able to use your website.

CSS fallback as a complement to JavaScript polyfill

Unlike in JavaScript part, it is impossible to do placeholders feature detection in CSS. The only thing left is targeting specific browsers – IE 9 and below in this case.

<!--[if lte IE 9]> <html lang="en" class="no-js no-placeholder"> <![endif]-->
<!--[if gt IE 9]><!--> <html lang="en"> <!--<![endif]-->
<head>
	<!-- ... -->
	<script>
		// removes "no-js" class name from <html> element; remove this <script> part if you use Modernizr, because it will remove the class name for you
		;(function(window, document) {
			document.documentElement.className = document.documentElement.className.replace('no-js', 'js');
		}(window, document));
	</script>
</head>
<!-- ... -->

Now, we have to repeat the placeholder text and wrap it with some tags:

<div class="item">
	<input type="email" name="" value="" placeholder="Email" class="textfield" id="input-email" />
	<label for="input-email">Email</label>
</div>

And of course, make the text visible when necessary:

html.no-placeholder.no-js .item label {
	display: block;
}

CSS fallback as the only solution

Bypassing JavaScript polyfill and applying only CSS fallback is very similar to what I wrote previously. The only difference is this (no <script> part here!):

<!--[if lte IE 9]> <html lang="en" class="no-placeholder"> <![endif]-->
<!--[if gt IE 9]><!--> <html lang="en"> <!--<![endif]-->
html.no-placeholder .item label {
	display: block;
}

Demo

I combined everything in the demo. Feel free to investigate the source code of the demo page and use the stuff in your projects. You should try the demo on browsers that do not support input placeholders, such as IE 9 or below.

See the demo.

&