18

I have an input like this:

<input value="My text" placeholder="Placeholder">

When I type something in the input the placeholder text will disappear, that's quite obvious.

Now, what I want to do is that I want the placeholder text to stay when the user types so you can see the placeholder text as a background text behind the original text:

placeholder

EDIT: I also want to be able to change the background-text using JavaScript.

6 Answers6

19

Much better solution with ease effect via CSS. Take a look: http://jsfiddle.net/csdtesting/wbqq129q/

  • Before typing:

enter image description here

  • While typing:

enter image description here

Code:

#login {
  font-size: 12px;
  margin: 0 auto;
  width: 700px;
}
#login li {
  float: left;
  list-style: none;
  margin-left: 30px;
  position: relative;
}
#login li:first-child {
  margin-left: 0;
}
label {
  line-height: 40px;
  position: absolute;
  right: 120px;
  top: 0;
  bottom: 0;
  -moz-transition: 0.3s right ease;
  -ms-transition: 0.3s right ease;
  -o-transition: 0.3s right ease;
  -webkit-transition: 0.3s right ease;
  transition: 0.3s right ease;
  z-index: 0
}
input {
  color: transparent;
  font-size: 12px;
  height: 35px;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
  -moz-transition: 0.3s all ease;
  -ms-transition: 0.3s all ease;
  -o-transition: 0.3s all ease;
  -webkit-transition: 0.3s all ease;
  transition: 0.3s all ease;
}
input[type="email"],
input[type="password"] {
  border: 1px solid #ccc;
  height: 35px;
  padding: 0 10px;
  width: 240px;
  position: relative;
  -moz-box-shadow: inset 0 0 10px rgba(0, 0, 0, .06);
  -webkit-box-shadow: inset 0 0 10px rgba(0, 0, 0, .06);
  box-shadow: inset 0 0 10px rgba(0, 0, 0, .06);
  z-index: 2;
}
input[type="email"] {
  color: rgba(47, 130, 194, .8);
}
/* Placeholder */

input[type="email"]:-moz-placeholder {
  color: rgba(47, 130, 194, .6);
}
input[type="email"]:-ms-input-placeholder {
  color: rgba(47, 130, 194, .6);
}
input[type="email"]::-webkit-input-placeholder {
  color: rgba(47, 130, 194, .6);
}
/* Label */

input[type="email"] + label {
  color: rgb(47, 130, 194);
}
input:focus + label {
  right: 10px;
}
input[type="email"]:focus,
input[type="password"]:focus {
  background-color: rgba(255, 255, 255, .8);
}
/* Submit */

input[type="submit"] {
  background-color: #333;
  background: -moz-linear-gradient(bottom, #333, #444);
  background: -ms-linear-gradient(bottom, #333, #444);
  background: -o-linear-gradient(bottom, #333, #444);
  background: -webkit-linear-gradient(bottom, #333, #444);
  background: linear-gradient(bottom, #333, #444);
  border: 1px solid #222;
  color: #fff;
  cursor: pointer;
  height: 35px;
  width: 110px;
}
<form id="login">
  <ul>
    <li>
      <input id="email" name="email" placeholder="Your Email" title="Your Email" type="email" required />
      <label for="email">Your Email</label>
    </li>
  </ul>
</form>
Giannis Grivas
  • 3,374
  • 1
  • 18
  • 38
  • 2
    But that's not what I want to achieve. –  Oct 12 '14 at 11:11
  • 1
    @super Yes, but I can't imagine why you would ever want to keep the placeholder there. It's terrible design and looks extremely ugly. – sam1370 Jul 12 '19 at 20:40
15

Hard to think of a good usecase for such a behaviour, as it is blocking some of the users input.

An easy way would be to use input::after but this is not supported by any browser right now (thanks @JukkaK.Korpela).

But you can use a wrapper element and a data attribute, as follows:

<div class="placeholder" data-placeholder="my placeholder">
    <input value="My text" />  
</div>

With this css:

.placeholder
{
    position: relative;
}

.placeholder::after
{
    position: absolute;
    left: 5px;
    top: 3px;
    content: attr(data-placeholder);
    pointer-events: none;
    opacity: 0.6;
}

Resulting in: enter image description here

Click here for jsFiddle demo.


Since you will have to do a lot of tweaking to make this look good, you may also consider using the wrapping <div> element as a input "look alike":

<div class="editable" data-placeholder="my placeholder">
    <input type="text" value="my Text" />
</div>

CSS:

.editable
{
    position: relative;
    border: 1px solid gray;
    padding: 3px;
    background-color: white;
    box-shadow: rgba(0,0,0,0.4) 2px 2px 2px inset;
}

.editable > input
{
    position: relative;
    z-index: 1;
    border: none;
    background-color: transparent;
    box-shadow: none;
    width: 100%;
}

.editable::after
{
    position: absolute;
    left: 4px;
    top: 5px;
    content: attr(data-placeholder);
    pointer-events: none;
    opacity: 0.5;
    z-index: 1;
}

Click here for the Demo 3. (with mocked <input />)

Click here for the Demo 2. (with contenteditable)

Nico O
  • 13,762
  • 9
  • 54
  • 69
  • Nice, but for me the "my placeholder" text is a slight bit under the "My text awd", it happend in both Chrome & Firefox, anyway to fix that? –  Oct 12 '14 at 10:55
  • Not in a way you'd like. You could make a transparent background for the `` and use `z-index` to change the stacking, but this is becoming quite ugly: http://jsfiddle.net/dkoruadc/1/ . You are also likely to run into trouble with different browsers and OS. – Nico O Oct 12 '14 at 11:00
  • The text written by the user will also become less readable. Why are you at the first place trying this ? – Meer Oct 12 '14 at 11:02
  • @Meer are you addressing the OP or me? I'am trying this to help and show possibilities. I did not say it's a good idea to use this in production. – Nico O Oct 12 '14 at 11:04
  • @Nico I am asking Murplyx. as i think it is not a good practice. – Meer Oct 12 '14 at 11:06
  • 1
    `input::after` just isn’t supported by current browsers; there is nothing invalid in it (CSS pseudoelements are not part of HTML markup, and HTML rules don’t apply to them). – Jukka K. Korpela Oct 12 '14 at 13:45
  • Thank you very much for your reply, @JukkaK.Korpela I simplified the statement, as it was not important to answer the question. It should be less confusing or less incorrect now. – Nico O Oct 12 '14 at 14:00
3

You could try doing something like this:

HTML:

<div class="wrapper">
  <input type="text">
  <span class="placeholder">Placeholder</span>
</div>

CSS:

.wrapper{
  position: relative;
}

input {
  font-size: 14px;
  height: 40px;
}

.placeholder {
  position: absolute;
  font-size:25px;
  pointer-events: none;
  left: 1px;
  top: 1px;
  transition: 0.1s ease all;
}

input:focus ~ .placeholder{
  top: 1px;
  font-size: 11px;
}

JSFiddle

Kay
  • 65
  • 1
  • 7
  • 1
    This is by far the most elegant solution. I was going to have nightmares of me filling inputboxes with 2 sets of characters showing at the same time (as per previous answers), but yo saved me – juanm55 Aug 13 '20 at 23:08
  • The JSFiddle is still showing the placeholder text on top of the user's entered text - is this how its supposed to work or has this solution broken over time? Just checking as I like this idea and would like to try it. – Christopher Nov 29 '21 at 14:41
  • Dude, this is the cleanest implementation I have ever seen. You are a legend. Thank you. – Defacto Aug 12 '23 at 19:11
1

.box {
  border: 1px solid;
  border-radius: 10px;
  padding: .25rem 1rem 1rem;
  color: #555;
  font-family: sans-serif;
  display: flex;
  flex-direction: column;
  width: max-content;
}

.wrapper {
  position: relative;
  width: 450px;
}

.wrapper * {
  font-size: 1.25rem;
  letter-spacing: 2px;
  font-family: monospace;
  padding: .125rem .25rem;
  display: flex;
  width: calc(100% - 1rem);
}

input {
  width: 4000px;
  border: 0;
}

.placeholder {
  position: absolute;
  pointer-events: none;
  left: 0;
  top: 0;
  width: min-content;
}
<div class="box">
  <h2>Short Homepage Headline</h2>
  <p>Use up tp 30 characters</p>
  <div class="wrapper">
    <input type="text">
    <span class="placeholder">
      ______________________________
    </span>
  </div>
</div>

How about this for functionality, a good use case, and its attractiveness.
(trying to combat some of the negatives above, ha)

  1. the placeholder text was a limited number of underscores (30)?
  2. same font size, monospace, and letter spacing

enter image description here

This make a neat no-js character watcher for a headline writer. This way they will be able to see when it will break the template. But you don't necessarily have to be tied to it as far as a hard limit.

nic
  • 169
  • 1
  • 9
0

This could be done by using the 'onchange' handler. You would write a fancy function that would concat the remainder of the placeholder onto what the user has typed, and would also place the cursor at the end of the user's text.

Here's some untested, incomplete js/psuedocode to give you an idea:

userTextLength: 0, // measure of how many chars the user has typed; need this because the length itself won't be a valid measure, since we're modifying it in place. Note that we're using the DOM as a source of truth here... alternative method would be to store the user's text itself here, but let's run with this.
placeholder: "xx/yy/zz",
onchange: function() {
  boxText = document.querySelector('#elem').value;
  if (boxText.length === 1) { // special handling for the first character they type. (Using placeholder text at first.)
    this.userTextLength++;
    placeholder = boxText.slice(userTextLength);
    userText = boxText.slice(0, userTextLength);
    document.querySelector('#elem').innerHTML = userText + placeholder;
  }
  if (boxText.length < placeholder.length) { // this would mean they used backspace, which also needs to be handled.

  }
  else { // the normal case, should look quite similar to the first if block
    this.userTextLength += 1;
    userInput = 
  }
}

Something I haven't handled here is the cursor focusing. That will need an 'onfocus' event, and will use the userTextLength property as well to decide where to place it. For some help on doing that, this answer looks like it should be helpful.

Community
  • 1
  • 1
Kyle Baker
  • 3,424
  • 2
  • 23
  • 33
0

it is impossible, if it is, it will be very unattractive. But i have an idea can help you with jquery support.

You can view the demo here: http://hangaumy.com/order/

When you type, it will automatically add words in it (look like placeholder)