HTML5 placeholder and an alternative approach – introducing Robert’s playground

Looking at HTML5 and the placeholder functionality, it’s there to offer a hint to the user before they have started filling out something. But what if that’s not the best way?

In the placeholder section in the HTML5 specification it says:

User agents should present this hint to the user, after having stripped line breaks from it, when the element’s value is the empty string and the control is not focused (e.g. by displaying it inside a blank unfocused control).

Very clear and concise, and every web browser seem to have implemented in the same fashion. All good and well, right? Well, in my current project the UX Designer said she didn’t want that behavior, but rather the native way iOS handles it. My initial reaction was:

No, you’re wrong, of course. That’s not in the specification and not how web browsers implemented it.

However, after that I decided to take a more humble approach, to look at the iOS implementation, evaluate it and see which one was best. The very slight distinction between iOS and the HTML5 way is that iOS keeps the hint/placeholder text when the element gains focus and removes when you have actually started entering something.

And honestly, I must say that that is quite a nice way to do it. When you have set focus to the field, you might have forgotten what the hint said, but if it’s still there it makes thing a bit easier.

Introducing my playground and an alternative placeholder approach

I’ve created a new section of my web site, Robert Nyman’s playground. It’s like Tommy Lee’s Tommyland, but not the same. I wish. Or not. Well, maybe… Anyway… It’s where I will code things together to play around and show demos. As opposed to my HTML5 or CSS3 sections that are more tested and lists web browser support etc, the things in the playground might or might not work for you – if they don’t, and you know why, please let me know.

All the code is also available on GitHub in the robnymanplayground project, where you can look at it, fork it or experiment in any way.

In the playground, I have created the Alternative placeholder behavior where you can test this behavior and see if you prefer it. It works in all the latest versions of Firefox, Google Chrome, Safari, Opera and Internet Explorer, but should work in older versions as well. What it does is:

  • Offer placeholder behavior the way it is in iOS.
  • Clear the form fields from default placeholder text if nothing was entered.
  • Supports the behavior for password fields as well, switching between text and password field display.

The code looks like this:


<form action="index.html" novalidate>
    <input type="text" name="first-name" placeholder="Enter first name">
    <input type="text" name="last-name" placeholder="Enter last name">
    <input type="tel"  name="phone-no" placeholder="What is your phone no?">
    <input type="email" name="email-address" placeholder="Enter your e-mail address">
    <input type="text" name="user-pwd" data-type="password" placeholder="Choose a password">
    <input type="text" name="user-pwd-repeat" data-type="password" placeholder="Repeat password">

    <input type="submit" value="Send to myself">


var dataPlaceholders = document.querySelectorAll("input[placeholder]"),
    l = dataPlaceholders.length,
    // Set caret at the beginning of the input
    setCaret = function (evt) {
        if (this.value === this.getAttribute("data-placeholder")) {
            this.setSelectionRange(0, 0);
            return false;
    // Clear placeholder value at user input
    clearPlaceholder = function (evt) {
        if (!(evt.shiftKey && evt.keyCode === 16) && evt.keyCode !== 9) {
            if (this.value === this.getAttribute("data-placeholder")) {
                this.value = "";
                this.className = "active";
                if (this.getAttribute("data-type") === "password") {
                    this.type = "password";

    restorePlaceHolder = function () {
        if (this.value.length === 0) {
            this.value = this.getAttribute("data-placeholder");
            setCaret.apply(this, arguments);
            this.className = "";
            if (this.type === "password") {
                this.type = "text";

    clearPlaceholderAtSubmit = function (evt) {
        for (var i=0, placeholder; i<l; i++) {
            placeholder = dataPlaceholders[i];
            if (placeholder.value === placeholder.getAttribute("data-placeholder")) {
                placeholder.value = "";

    for (var i=0, placeholder, placeholderVal; i<l; i++) {
        placeholder = dataPlaceholders[i];
        if (placeholder.value.length === 0) {
        placeholderVal = placeholder.getAttribute("placeholder");
        placeholder.setAttribute("data-placeholder", placeholderVal);
        placeholder.value = placeholderVal;
        if (placeholder.type === "password") {
            placeholder.type = "text";
    else {
        placeholder.className = "active";
    // Apply events for placeholder handling         
    placeholder.addEventListener("focus", setCaret, false);
    placeholder.addEventListener("drop", setCaret, false);
    placeholder.addEventListener("click", setCaret, false);
    placeholder.addEventListener("keydown", clearPlaceholder, false);
    placeholder.addEventListener("keyup", restorePlaceHolder, false);
    placeholder.addEventListener("blur", restorePlaceHolder, false);
    // Clear all default placeholder values from the form at submit
    placeholder.form.addEventListener("submit", clearPlaceholderAtSubmit, false);

Call for a change?

What do you think? Do you prefer the iOS approach with a longer lingering of the hint text? Should we submit this as a change to HTML5 and current implementations in web browsers?

Posted in Developing,HTML5/HTML/XHTML,Technology,Web browsers |

Leave a Reply

Your email address will not be published. Required fields are marked *