2

I have a Wordpress plugin which I don't want to touch, so I'm hoping my goal can be achieved with CSS only. I have fiddled (no pun intended) with the CSS in Chrome Developer Tool but ended up with a mess all the time.

What I want is the label to be on top of the input field. "On top" meaning Z- not Y-axis. Below is the HTML structure.

<p>
  <label>Name<br>
    <span>
      <input type="text" name="your-name" value="" size="40">
    </span>
  </label>
</p>
TylerH
  • 20,799
  • 66
  • 75
  • 101
Gerard
  • 15,418
  • 5
  • 30
  • 52
  • I see what you meant. But then how would text typed into the input look with the label sitting on top of it? – j08691 Jun 02 '17 at 16:45
  • Without changes to the mark up, it cannot be done with CSS. You would at least need to wrap the text ("Name") in a span, so it could be absolutely positioned. And even then, the text would superimpose the text typed into the input. – Michael Benjamin Jun 02 '17 at 16:46
  • I will move the label to the position it has now with a transition on focus of the input field. – Gerard Jun 02 '17 at 16:46

2 Answers2

7

With a small markup change and a script you can do this

The script simply append the user value to its value attribute, so one can use CSS to style it

p label {
  position: relative;
}
p label input {
  margin-top: 10px;
}
p label input[required] + span::after {
  content:  ' *';
  color: red;
}
p label span {
  position: absolute;
  top: 2px;
  left: 5px;
  pointer-events: none;
  transition: top .5s;
}
p label input:not([value=""]) + span,
p label input:focus + span {
  top: -20px;
}
<p>
  <label>
      <input oninput="this.setAttribute('value', this.value)" type="text" name="your-name" value="" size="40" required>
      <span>Name</span>
  </label>
</p>

Since changing a HTML5 input's placeholder with CSS is a hot topic, here is a few more alternatives, with a simpler, more reusable markup structure

.placeholder {
  position: relative; padding-top: 15px;
}
.placeholder label {
  position: absolute; top: 17px; left: 5px;
  pointer-events: none; transition: top .5s;
}
.placeholder input[required] + label::after {
  content:  ' *'; color: red;
}
.placeholder input:not([value=""]) + label,
.placeholder input:focus + label {
  top: -5px;
}
<div class="placeholder">
  <input oninput="this.setAttribute('value', this.value)" type="text" name="name" value="" required>
  <label>Name</label>
</div>

Since the script is very small, I applied it inline, though one can of course add the same behavior with an external event handler, like this, and target more than one input.

window.addEventListener('load', function() {
  var placeholders = document.querySelectorAll('.placeholder input');
  for (var i = 0; i < placeholders.length; i++) {
    placeholders[i].addEventListener('input', function() {
      this.setAttribute('value', this.value);
    })
  }
})
.placeholder {
  position: relative; padding-top: 15px;
}
.placeholder + .placeholder {
  margin-top: 10px;
}
.placeholder label {
  position: absolute; top: 17px; left: 5px;
  pointer-events: none; transition: top .5s;
}
.placeholder input[required] + label::after {
  content:  ' *'; color: red;
}
.placeholder input:not([value=""]) + label,
.placeholder input:focus + label {
  top: -5px;
}
<div class="placeholder">
  <input type="text" name="name" value="" required>
  <label>Name</label>
</div>
<div class="placeholder">
  <input type="text" name="email" value="" required>
  <label>Email</label>
</div>
<div class="placeholder">
  <input type="text" name="address" value="">
  <label>Address</label>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • @Diego Thanks...and it can :) – Asons Jun 02 '17 at 17:01
  • 1
    In thinking about it, this answer can actually be very useful in a general toolkit. It eliminates the need to style an actual placeholder, which happens to be the [**second most popular CSS question on this site**](https://stackoverflow.com/questions/tagged/css?sort=votes) (by votes). Nice work, @LGSon. – Michael Benjamin Jun 02 '17 at 17:03
  • I want to animate the label and move it back above the input field upon focus (not a question, I'll figure out how to do that). It avoids the need for the oninput, so HTML can stay as it was. – Gerard Jun 02 '17 at 17:06
  • @Gerard Nope, you'll need the `oninput` either way, or else when it loses focus it will slide back – Asons Jun 02 '17 at 17:08
  • @Gerard Updated my answer with a transition – Asons Jun 02 '17 at 17:13
  • 1
    Beautiful! Thanks again. – Gerard Jun 02 '17 at 17:14
  • @Michael_B Thanks...I checked that post, and no one posted anything like I did here. Do you think it would be okay to post a version of this there? – Asons Jun 02 '17 at 17:22
  • 1
    Sure, I don't see why not. There are 42 answers already, however, so don't expect a lot of attention, at least until you're voted up a bit. You can also put a link to this answer in that question's comment section. – Michael Benjamin Jun 02 '17 at 17:25
  • @LGSon: you may want to consider adding a red asteriks :after the label when the :required attribute is present at the input field – Gerard Jun 02 '17 at 17:33
0

You can use the placeholder attribute in the input tag:

<p>
  <label>Name<br>
    <span>
      <input type="text" name="your-name" value="" placeholder="Name" size="40">
    </span>
  </label>
</p>
Johannes
  • 64,305
  • 18
  • 73
  • 130
  • Yeah I know. But that would require a change of the plugin code and I want to avoid that. Thanks though. – Gerard Jun 02 '17 at 16:43