0

I am using Bootstrap-Vue to build a form, and I would like the placeholder text to animate so that it sits on top of the input using CSS Transitions.

I currently have this bit of code which is generated by Bootstrap-Vue:

<form class="form" _lpchecked="1">
  <div role="group" class="form-group">

    <label for="year" class="d-block form-control-placeholder">Year</label>

    <div>
      <input id="year" name="year" type="text" class="form-control">
    </div>

  </div>
</form>

I can't change the above markup as Bootstrap-Vue uses components for inputs and form groups which generate the markup for me. Therefore other similar questions asked on StackOverflow don't answer my question.

As for my CSS, it looks like this:

.form-group {
  position: relative;
  margin-bottom: 1.5rem;
}

.form-control-placeholder {
  position: absolute;
  top: 0;
  padding: 7px 0 0 13px;
  transition: all 200ms;
  opacity: 0.5;
  color: red;
}


.form-control:focus + .form-control-placeholder,
.form-control:valid + .form-control-placeholder {
  font-size: 75%;
  transform: translate3d(0, -100%, 0);
  opacity: 1;
}

The Codepen for the above code is here: https://codepen.io/Canvasandcode/pen/OJJZLmM

ImranR
  • 15
  • 4

2 Answers2

1

Your code is pretty close to the desired approach!

But there are minor things you just need adjust to make it work;

First, delete <div> wrapper outside of <input> make them adjacent

switch the <input> and <label> so .class:focus/valid + .class CSS selector can work. the reason is because the way your wrote the + is referring to the next adjacent element.

then add required="required" to your <input> in order to use CSS :valid.

That's it! cheers. The following code snippet is just the changes based on your own code.

.form-group {
  position: relative;
  margin-bottom: 1.5rem;
}

.form-control-placeholder {
  position: absolute;
  top: 0;
  padding: 7px 0 0 13px;
  transition: all 200ms;
  opacity: 0.5;
  color: red;
}

.form-control:focus + .form-control-placeholder,
.form-control:valid + .form-control-placeholder {
  font-size: 75%;
  transform: translate3d(0, -100%, 0);
  opacity: 1;
}
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">


<div class='container m-5'>
<form class="form" _lpchecked="1">
  <div role="group" class="form-group">
    <input id="year" name="year" type="text" class="form-control" required="required">
    <label for="year" class="d-block form-control-placeholder" required="required">Year</label>
  </div>
</form>
  </div
Yunhai
  • 1,283
  • 1
  • 11
  • 26
  • Thanks that helps! However I'm unable to change the HTML markup as I'm using Bootstrap-Vue to generate the markup. Is there anyway to refactor the CSS you have written to match the mark up I provided? – ImranR Nov 07 '19 at 10:01
  • @ImranR No. Unfortunately, as the duplicated markup said. You want to do previous sibling, parent selector that is not supported in pure css. If html is the only thing you cannot modify, JavaScript is the way to go. As you said you are using Bootstrap-Vue, there must be a way or always some ways to modify and regenerate the desired markup. Otherwise there is not point to use that framework that has no control on markup, which imo is impossible. – Yunhai Nov 07 '19 at 16:09
  • Thanks, I thought so - I ended up using javascript to add the class on focus and remove on blur if the value of the input is empty. Thanks for the heads up – ImranR Nov 07 '19 at 16:59
-1
HTML:
<form class="form" _lpchecked="1">
  <div role="group" class="form-group">
    <div>
      <input id="year" name="year" type="text" class="form-control">
      <label for="year" class="d-block form-control-placeholder">Year</label>
    </div>
  </div>
</form>

CSS:
.form-group {
    position: relative;
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
}

.form-control{
    position: absolute;
    top: 0;
    left: 0;
}

.form-control-placeholder {
    position: relative;
    padding: 7px 0 0 13px;
    transition: all 200ms;
    z-index: 111;
    opacity: 0.5;
    color: red;
    width: 300px;
    height:40px;
}

.form-control:focus + .form-control-placeholder {
    font-size: 75%;
    transform: translate3d(0px, -100%, 0px);
    opacity: 1;
}