Made to Order Software Corporation Logo

Put the label of an HTML Input inside the Input element

Reflection of trees in a mountain lake.

Update:

With HTML5 running on pretty much all platforms, you want to use the placeholder attribute instead of any sort of tricks to place a label inside your input widgets.

This is done like this:

<input type="text" placeholder="Phone Number"/>

This example will show "Phone Number" inside the input box until the user types some text in that box.

You can test with the box right here. This is just that one <input .../> tag I placed in my page HTML. (It is not in a form, but the widget itself will work as expected.)

For additional details, I suggest you check the MDN page about the input tag.


In fact, HTML5 defines the placeholder="..." attribute, but the trick is really done using the following CSS trick which you can use with any element, a differently named attribute, and absolutely any CSS effects on the font.

// HTML
<div contenteditable="true"></div>

// CSS
[contenteditable=true]:empty:before
{
  content: attr(placeholder);
  display: block; /* For Firefox -- you may need to use "inline-block" */
}

In most cases you want such an effect only when an element has the contenteditable attribute set to true, hence the CSS selector. But the most important aspects of this CSS code are the empty selector, the before pseudo element, and the attr() reference.

Note: In most cases we see contenteditable set on a <div> tag. Know, however, that it works on pretty much any visible tag.

There is one drawback, when you delete the last character from a contenteditable element, the browsers are likely to keep a <br/> tag in there (to avoid having the element collapse to nothingness.) So the placeholder does not reappear unless you have some JavaScript code that can remove the lone <br/> element. Still it's much easier to do it this way and avoid all sorts of other pitfalls when trying to do it using JavaScript.

Example:

 

Note: I use a small JavaScript here to create the <div> tag with the contenteditable attribute because my CMS inline editor leaves an &nbsp;, a newline, and a tab in an inline example. The JavaScript creates a clean version, however. The example also includes some font color and style changes.


Old Post:

Today I was looking into creating a small module for Drupal that would allow me to move the labels of my HTML Input elements inside the element itself. This is useful for small forms such as the Search, Log In, and Newsletter Subscription forms. Bigger forms are better left alone (I think.)

First, it took me some time to find the right keywords to search with. Once I included Label Inside Input Element, I started to get good answers.

Before it was done by setting some default value in the Input element. There are two drawbacks with that method: one you need to test and remove that default value automatically. If the user enters the default as his answer, it won't work (in many cases this is not a problem, but still, it happens.)

The better solution used today is to move the label of the Input element from before the element to under the element and make the input element transparent1. Then, a little CSS and JavaScript and everything will fall in place: the label appears in the Input element until someone types text in it; setup the color in the CSS; still works even if JavaScript is not available.

References:

  • 1. Note that if your Input element cannot be transparent, you can instead place the label in front of the input element. It has just one small draw back: the users can click on the label in that case. It shouldn't matter although there can be some side effects, yet if you need to have a background color different on your Input element than what you otherwise have in the background of your form, that's probably your only solution.