Search code examples
htmlcsscss-transforms

Why is transform-origin: bottom not working?


I'm trying to get a line appear "under" an input box when in focus. For some reason transform-origin "left" (that is if I change it to "right" it will appear from the right side, but with "left" it appears from the left) works but 'bottom' doesn't and it keeps appearing on top.

.wrap-input{
    width: 100%;
    position: relative;
    border-bottom: 2px solid #adadad;
    height: 49px;
  }
  .inputForm {
    font-size: 15px;
    color: #555555;
    line-height: 1.2;
    display: block;
    width: 100%;
    height: 45px;
    padding: 0 5px;
    outline: none;
    border: none;
  }

  .wrap-input::before{
    content: '';
    height: 2px;
    background: linear-gradient(90deg, rgba(128,0,0,1) 15%, rgba(238,174,150,1) 49%, rgba(128,0,0,1) 85%);
    display: block;
    transform: scale(0, 1);
    transition: transform 0.4s cubic-bezier(1, 0, 0, 1);
    transform-origin: left bottom;/*this line is problem*/
  }
  .wrap-input:hover::before {
  transform: scale(1, 1)
  }
 <div class="wrap-input" data-validate="Valid email is: info@johndoe.com">
    <input class="inputForm" type="text" name="email" placeholder="Email">               
</div>


Solution

  • I suspect that transform-origin isn't what you require - it tells the system the point from which any tranformation is to take place - it's relative to the element it's in, not to any 'owner'/parent/ancestor.

    To position the pseudo element under the input element this snippet gives it position absolute and position left 0 and bottom 0 - these are relative to the actual div itself.

    .wrap-input {
      width: 100%;
      position: relative;
      border-bottom: 2px solid #adadad;
      height: 49px;
    }
    
    .inputForm {
      font-size: 15px;
      color: #555555;
      line-height: 1.2;
      display: block;
      width: 100%;
      height: 45px;
      padding: 0 5px;
      outline: none;
      border: none;
    }
    
    .wrap-input::before {
      content: '';
      height: 2px;
      background: linear-gradient(90deg, rgba(128, 0, 0, 1) 15%, rgba(238, 174, 150, 1) 49%, rgba(128, 0, 0, 1) 85%);
      display: block;
      transform: scale(0, 1);
      transition: transform 0.4s cubic-bezier(1, 0, 0, 1);
      transform-origin: left center;
      position: absolute;
      left: 0;
      bottom: 0;
      width: 100%;
    }
    
    .wrap-input:hover::before {
      transform: scale(1, 1)
    }
    <div class="wrap-input" data-validate="Valid email is: info@johndoe.com">
      <input class="inputForm" type="text" name="email" placeholder="Email">
    </div>