10

Instead of labeling each field in a form, it is sometimes preferable (from a design standpoint) to have placeholder text in each field. For example, instead of having this:

             ----------------------------------
Full Name:  |                                  |
             ----------------------------------

you have this:

 ----------------------------------
| Full Name                        |
 ----------------------------------

The when you click in the field, the text disappears and you can write whatever you want. If you skip over the field without entering any text, then the placeholder reappears.

I've seen this done many ways, but all methods involve JavaScript. For example, Twitter does a decent job on their signup page but if Javascript is disabled you end up typing your name over the word 'Full name'.

I'm looking for a CSS-only method that would work even with JavaScript disabled. The only potential solution I've come up with is to set the background of the <input> tag to an image of the desired text and then use the input:focus pseudo-class to clear the background image when someone clicks on the text box. This seems to work but it would be nice not to have to use images.

Does anyone know of a good resource on how to do this?

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
David Jones
  • 10,117
  • 28
  • 91
  • 139
  • It would be nice if you explained what the placeholder attribute does for those not well-informed. Like I was a minute ago. I don't think older CSS (pre-HTML5/CSS3 era) can do this... – TheZ Jul 06 '12 at 23:52
  • 3
    I think you're pushing CSS into areas in which it cannot (yet) perform the tasks you're expecting of it. There are... *possibilities* with `::before` and `::after` pseudo-elements, but they're unreliable with `input` elements, and any browser that implements pseudo-elements will also implement the `placeholder` attribute. – David Thomas Jul 06 '12 at 23:52
  • By "place holder" I presume he means a textfield that displays example text (Eg: "Your Name Here") until the user selects it. – username Jul 06 '12 at 23:57
  • @username: That's right. I'll make it more clear in my post. – David Jones Jul 06 '12 at 23:59
  • @DavidThomas you are wrong: for example IE8 doesn't support the placeholder attribute but it supports the after and before pseudo-elements. – Knu Jul 07 '12 at 01:54
  • @knu i dont believe :before and :after are supported on the input element though, or for that matter any non-container elements http://stackoverflow.com/questions/2587669/css-after-pseudo-element-on-input-field – DMTintner Nov 25 '13 at 11:00
  • @DMTintner you know you can put them *inside* their corresponding label right? – Knu Nov 25 '13 at 23:45

5 Answers5

31

This is the preferred method, and works in all current browsers:

<input type="text" name="" placeholder="Full Name"/>

This version works for IE9 and before:

<input type="text" name="" value="Full Name" onfocus="value=''" onblur="value='Full Name'"/>
ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
Jay
  • 1,086
  • 11
  • 25
  • 15
    I might be missing something obvious here, but won't the second version set the value to "Full Name" even after a user enters a value? – Chris Owens Jun 12 '13 at 11:00
  • Yes, it will -- there needs to be a conditional statement there indicating it will only revert to 'Full Name' if the value on blur is `value=''` – code-sushi Nov 03 '14 at 16:54
  • 2
    The OP asked if it was possible to do in CSS only. – Wes Modes May 18 '16 at 05:22
15

You can do this with a <label> placed behind the index using z-index and a transparent background-color on the <input>. Use :focus to change to a white background.

:first-line has some Firefox issues.

Demo: http://jsfiddle.net/ThinkingStiff/bvJ43/

Note: See code-sushi's comment below for blur issues: Placeholder text in an input field with CSS only (no JavaScript)

Output:

enter image description here

HTML:

<label class="input">enter name<input /><label>​

CSS:

.input {
    color: gray;
    display: block;
    font-size: small;
    padding-top: 3px;
    position: relative;
    text-indent: 5px;
}

input {
    background-color: transparent;
    left: 0;
    position: absolute; 
    top: 0;   
    z-index: 1;
}

input:focus, input:first-line {
    background-color: white;
}
Community
  • 1
  • 1
ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
  • This feels really close. If we could come up with a way to allow for cases where the input is shorter than the placeholder it would be perfect... – David Jones Jul 07 '12 at 04:25
  • @danielfaraday I think in almost all scenarios, the data will be longer than the placeholder. Keep the placeholder font small and the labels short and you're probably good. You could play around with `first-line` some more, but I couldn't get anything to make it take up the whole `input`. – ThinkingStiff Jul 07 '12 at 04:33
  • 1
    @Knu: could you post your code? Your previous link looks the same to me (placeholder text appears on blur). – David Jones Jul 07 '12 at 11:31
  • So the answer's length matters: kind of a letdown. – Knu Jul 15 '12 at 01:23
  • You are missing a critical component needed for preventing the label from "bleeding through" once the user is no longer focused on that particular field. Hint: `input:valid { background-color:white; }`. The pseudo-class `:valid` obtains whenever a field has any value other than `''`. – code-sushi Oct 31 '14 at 19:03
  • Still no bueno. The label reappears on-blur. You need to specify an `input:valid` class to take care of that problem. – code-sushi Nov 03 '14 at 17:02
1

Try this:

HTML

<div>
    <input type="text" id="text"></input>
    <label for="text">required</label>
</div>

CSS

.text-wrapper {
    position: relative;
}
.text-input-label {
    position: absolute;
    /* left and right properties are based on margin, border, outline and padding of the input text field */
    left: 5px;
    top: 3px;
    color: #D1D1D1;
}
#text:focus + label {
    display: none;
}

Working Fiddle

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
  • Still no bueno -- on blur you can see the label. You need to set a class for `input:valid` to make the label stop showing. – code-sushi Nov 03 '14 at 17:01
0

Try this: it solves the overflowing placeholder and multi-input cases. The trick is to move the labels behind their inputs and reorder them visually.

You don't need an extra div to achieve what you want.

Knu
  • 14,806
  • 5
  • 56
  • 89
0

All of the presumably CSS-only answers above have neglected a critical component which is required in order to prevent the label acting as a pseudo-placeholder from "bleeding through" once the user is no longer focused on that particular field.

Hint:

input:valid { background-color:white; }

The pseudo-class :valid obtains whenever a field has any value other than ''. So when your user enters anything in the field of his or her own, the label displayed there will stop being displayed.

Be advised with <input type="email" /> fields, the pseudo-class :valid does and will actually require input of a valid email format (e.g. "xxxx@xxx.com" -- or .net or .org, etc.).

Full instructions how to do this here: http://css-tricks.com/float-labels-css/

code-sushi
  • 719
  • 3
  • 7
  • 23