56

I want the placeholder to move to the top when the textbox is on focus and also while the user is typing.

I'm not sure if this is just html/css or any javascript too.

My current css looks like this, and I have no js code yet:

input:focus::-webkit-input-placeholder {
    font-size: .75em;
    position: relative;
    top: -15px; 
    transition: 0.2s ease-out;
}

input::-webkit-input-placeholder {
    transition: 0.2s ease-in;
}

input[type="text"]:focus, input[type="password"]:focus {
    height: 50px;
    padding-bottom: 0px;
    transition: 0.2s ease-in;
}

input[type="text"], input[type="password"] {
    height: 50px;
    transition: 0.2s ease-in;
}

It almost does the work but the placeholder disappears when I start typing. I'm using twitter-bootstrap, if that makes anything easier!

Thanks.

Bivo Kasaju
  • 1,143
  • 3
  • 13
  • 28
  • If you just inspect that page you'll see that it's not a placeholder that they're manipulating it's a DIV that is floating on top of the INPUT. You should be able to replicate what's happening just by looking at the code on that site. – Billy Moat Mar 11 '16 at 14:07
  • Couldn't see any placeholder code, and I was so fixated on that I didn't know they were using another div. So there's no way of making placeholder stay while typing? – Bivo Kasaju Mar 11 '16 at 14:09
  • Google's Material Design Lite uses a similar behaviour. [Here](http://codepen.io/joshadamous/pen/yyyqJZ) is an example of how to implement such a feature with HTML/CSS/jQuery. I think you will somehow need JS in general to make it work fine all around. – Arnold Stoba Mar 11 '16 at 14:12
  • The linked page doesn't use JS. It's not needed. You can use the `pointer-events` property and the `:focus` selector to work your way around it with just CSS. – Enrico Mar 11 '16 at 14:15
  • @BivoKasaju the provided link doesnt work any more, consider changing it or modifying the question – trainoasis Jun 27 '17 at 08:22
  • this is also good example on the same matter https://www.cssscript.com/pure-css-floating-label-pattern-bootstrap/ – Mist May 29 '18 at 12:10

8 Answers8

101

You could do it like this

HTML:

<div>
  <input type="text" class="inputText" />
  <span class="floating-label">Your email address</span>
</div>

CSS:

input:focus ~ .floating-label,
input:not(:focus):valid ~ .floating-label{
  top: 8px;
  bottom: 10px;
  left: 20px;
  font-size: 11px;
  opacity: 1;
}

.inputText {
  font-size: 14px;
  width: 200px;
  height: 35px;
}

.floating-label {
  position: absolute;
  pointer-events: none;
  left: 20px;
  top: 18px;
  transition: 0.2s ease all;
}

Working JSFiddle here https://jsfiddle.net/273ntk5s/2/

  • 1
    For some reason my floating label is appearing below the text box. Maybe bootstrap is messing up with my code. – Bivo Kasaju Mar 11 '16 at 14:43
  • You could change the `top:18px` in `.floating-label` according to your dom setup. So that the floating-label sits within the input. –  Mar 11 '16 at 14:48
  • I figured a way around, gave position absolute to floating label, and a z-index of >1 because it was hiding behind the text box! It's working, thanks @DivakarDaas – Bivo Kasaju Mar 11 '16 at 14:49
  • Cool. Good for you. Happy coding :) –  Mar 11 '16 at 14:50
  • @DivakarDaas oops minor issue! The text goes back to it's original "placeholder" form after the user has typed and the box is out of focus, so two texts kinda overlap! Need to figure out a way to keep the "placeholder" small at the top while the box contains text. I think that's javascript? – Bivo Kasaju Mar 11 '16 at 14:54
  • 1
    @BivoKasaju You could do it with css by just adding this `input:not(:focus):valid ~ .floating-label`. See my updated answer and JSFiddle. –  Mar 11 '16 at 15:16
  • @DivakarDaas Super Awesome!! Thanks mucho! No idea what :not :valid does, but I'm super happy that it works! :) – Bivo Kasaju Mar 11 '16 at 15:22
  • 6
    `:not(:focus)` will check if the input element is not focused and `:valid` checks if the input value is valid or not. Note: The `:valid` works when you add `required` to your html input tag. –  Mar 11 '16 at 15:25
  • 6
    Maybe I'm late to the party, but above solution works, except when the input contains `type="email"`. When you tab outside this field, the floating label will grow again to it's former size. Anyone have a workaround / solution for this? – Martin van Houte Jan 25 '17 at 15:02
  • It's not working with two textboxes, Any other help? – user9437856 Jun 29 '18 at 12:45
  • 4
    I think the answer is not complete, floating-label position is absolute and moved relative to page – Abdulbosid Aug 28 '19 at 05:35
26

.user-input-wrp {
 position: relative;
 width: 50%;
}
.user-input-wrp .inputText{
 width: 100%;
 outline: none;
 border:none;
 border-bottom: 1px solid #777;
  box-shadow: none !important;
}
.user-input-wrp .inputText:focus{
 border-color: blue;
 border-width: medium medium 2px;
}
.user-input-wrp .floating-label {
 position: absolute;
 pointer-events: none;
 top: 18px;
 left: 10px;
 transition: 0.2s ease all;
}
.user-input-wrp input:focus ~ .floating-label,
.user-input-wrp input:not(:focus):valid ~ .floating-label{
 top: 0px;
 left: 10px;
 font-size: 13px;
 opacity: 1;
}
<h1>The floating label</h1>
<div class="user-input-wrp">
  <br/>
  <input type="text" class="inputText" required/>
  <span class="floating-label">Your email address</span>
</div>

Modified the code from @user1846747 a little.

Dinu Mathai
  • 471
  • 6
  • 7
12

Only using HTML and css

.searchformfld{
    position: relative;
    margin: 5px 0px;
}
.searchformfld label{
    position: absolute;
    padding-left: 10px;
    top:15px;
    cursor: text;

}
.searchformfld input:focus + label,.searchformfld input:not(:placeholder-shown) + label{
    opacity:1;
    transform: scale(.9) translateY(-100%) translateX(-10px);
    color:#000;
}
.searchformfld input:focus{
    border:1px solid #000;
    outline-color: #000;
}
.searchformfld{
    padding: 15px;
    margin:15px 0px;
}
.searchformfld input{
    width:100%;
    padding-left: 10px;
}
.searchformfld label,.searchformfld input{
    transition: all 0.2s;
    transition-timing-function: ease;
    transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
    opacity:0.5;
}
<div class="searchformfld">
            <input type="text" class="candidateName" id="candidateName" name="candidateName" placeholder=" "/>
            <label for="candidateName">Candidate name</label>
        </div>
Srinivasan N
  • 733
  • 8
  • 9
10

You can try the below code. It only uses HTML and CSS and does not reply on Javascript or component libraries:

.text-field {
        position: relative;
        margin: 10px 2.5px 20px 2.5px;
    }

input {
        display: inline-block;
        border: thin solid #fafafa;
        border-bottom: solid medium #999;
        color: #444;
        background-color: #fafafa;
        padding: 10px 10px 10px 10px;
        border-top-left-radius: 10px;
        border-top-right-radius: 10px;
    }

    input:focus {
            border: thin solid #32cd32;
            border-bottom: solid medium #32cd32;
            background-color:#fff;
        }

label {
        color: #999;
        position: absolute;
        pointer-events: none;
        left: 10px;
        top: 10px;
        transition: 0.2s;
    }

input:focus ~ label, input:valid ~ label {
        top: -10px;
        left: 15px;
        font-size: small;
        color: #32cd32;
        background-color:#fff;
        padding:0 5px 0 5px;
    }
<div class="text-field">
                <input type="text" required>
                <label>Input field 1</label>
            </div>

            <div class="text-field">
                <input type="text" required>
                <label>Input field 2</label>
            </div>
5

span{
  display:block;
  }
input:focus::-webkit-input-placeholder { color:transparent; }
input:focus:-moz-placeholder { color:transparent; } /* FF 4-18 */
input:focus::-moz-placeholder { color:transparent; } /* FF 19+ */
input:focus:-ms-input-placeholder { color:transparent; } /* IE 10+ */
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
$(document).ready(function() {
  $('input').focus(function(){
    placeholder = $(this).attr('placeholder');
    if(placeholder != undefined){
      $(this).parent().prepend('<span class="input-placeholder">'+placeholder+'</span>');
    }
  });
  $('input').blur(function(){
    $(this).parent().find('.input-placeholder').remove();
  });
});
</script>
<div>
  <input type="text" class="inputText" placeholder="Email adress" required/>
</div>
Alex
  • 51
  • 1
  • 1
  • ✔ This is the Cleanest way , It also works on your existing website & you dont have to add floating span manually to each input on whole website. !! – KRISHNA Jul 18 '22 at 07:49
5

The solution I want to propose deals with an input with the movement of the placeholder without the need for the required attribute

.inputField {
  position: relative;
}

.inputField input {
  padding: 8px 20px;
  padding-top: 18px;
  border: 1.8px solid rgba(107, 107, 107, 0.4);
  border-radius: 3px;
  width: 50%;
  color: black;
}

.inputField input:focus {
  border: 1.8px solid #6b6b6b;
  outline: none;
}

.inputField span {
  pointer-events: none;
  opacity: 0.5;
  position: absolute;
  padding-left: 20px;
  left: 0;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
  cursor: text;
}

.inputField input:focus+span,
.inputField input:not(:placeholder-shown)+span {
  top: 7px;
  -webkit-transform: scale(0.7) translateY(-10%) translateX(-8.5px);
  transform: scale(0.7) translateY(-10%) translateX(-8.5px);
}

.inputField input,
.inputField span {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-transition: all 0.2s;
  transition: all 0.2s;
  -webkit-transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
  transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
}
<div class="inputField">
  <input type="text" placeholder=" " />
  <span>Placeholder</span>
</div>
  • 1
    This is great, but have you noticed that if you click on the Placeholder it doesn't open the input? This is not necessary, but do you know a way to get this to work as well? – topsoftwarepro May 05 '21 at 07:51
  • Thank you for reporting this issue to me. I solved the problem by adding a css property to the tag: `pointer-events: none;` – Gian Marco Del Freo May 16 '21 at 09:58
4

That site isn't moving the placeholder, but placing a div (.floating-label) over the input, so when the input is focused the div just animates to be over the input. The key part here is using pointer-events: none; in the floating div, so when you click it the event goes through it to the input box behind it.

Enrico
  • 766
  • 8
  • 19
3

if your Floating label is not working when required attribute is removed, try this: using input:not(:placeholder-shown)

input:focus ~ .floating-label,
input:not(:placeholder-shown) ~ .floating-label{
  top: 8px;
  bottom: 10px;
  left: 20px;
  font-size: 11px;
  opacity: 1;
}

.inputText {
  font-size: 14px;
  width: 200px;
  height: 35px;
}

.floating-label {
  position: absolute;
  pointer-events: none;
  left: 20px;
  top: 18px;
  transition: 0.2s ease all;
}
<div>
  <input placeholder="" type="text" class="inputText" />
  <span class="floating-label">Your email address</span>
</div>
adebiyij
  • 41
  • 1