4

I am facing a problem: I am creating some inputs with different states; one of this states is when the text of the input is longer that the input itself: in this case the text that is hidden at the left of the input should fade out with a gradient transparency:

enter image description here

My code for now is this:

.Input {
    position: relative;
    width: 100%;
    border: none; 
    width: 200px;
}

.Input:before {
    content: '';
    position: absolute;
    bottom: 0;
    width: 100%;
    transition: border-bottom 0.5s ease;
    border-bottom: 1px solid gainsboro;
}

.Input input {
    margin-top: 20px;
    height: 40px;
    width: 100%;
    padding-left: 0;
    font-size: 16px;
    font-weight: 300;
    background-color: transparent;
    background-image: linear-gradient(to bottom, gainsboro 50%, tomato 50%);
    background-repeat: no-repeat;
    background-size: 0 11%;
    background-position: 50% 100%;
    transition: all 0.5s ease;
    box-shadow: none;
}

.Input h1 {
    font-size: 16px;
    color: gainsboro;
    font-weight: 400;
    position: absolute;
    pointer-events: none;
    left: 0;
    bottom: 0;
    transition: 0.5s ease all;
    width: 100%;
    line-height: unset;
}

.Input:hover:before {
    transition: border-bottom 0.5s ease;
    border-bottom: 1px solid dimgray;
}

input:focus {
    background-color: transparent;
    background-image: linear-gradient(to bottom, transparent 50%, tomato 50%);
    background-repeat: no-repeat;
    background-size: 100% 11%;
    background-position: 50% 100%;
    transition: all 0.5s ease;
}

input:focus,
input:not(:focus):valid {
    border: none;
    outline: none;
}

input:focus ~ h1, input:not(:focus):valid ~ h1 {
    color: tomato;
    transition: all 0.5s ease;
    transform: translateY(-25px);
}
<div class="Input">
<input type="text" class="Input" name="testInput" value="" data-id="" required>
<h1>
MyInput
</h1>
</div>
<br>

Any help will be welcome…

Thanks in advance!

  • for sure we will need some JS, i guess you should calculate the height taken by the text and this will involve the font-size,font-family, etc – Temani Afif Dec 17 '17 at 15:29
  • https://stackoverflow.com/questions/15161385/how-to-get-the-real-height-of-a-text – Temani Afif Dec 17 '17 at 15:34
  • I don't know why I have to calculate the height; what I need is to apply a gradient transparency to the text, which width is fixed, so no need for `parseInt(window.getComputedStyle($('input')[0]).width, 10);`. –  Dec 17 '17 at 15:47
  • but you said you want this gradient when he text is longer ? because the gradient is easy – Temani Afif Dec 17 '17 at 18:11
  • Yes, when the text is longer that the width, it needs a gradient like in the image… –  Dec 17 '17 at 18:35

1 Answers1

0

The idea to check if the text reach a particular length, if yes you show a hidden element.

In the example below I simplified to the test but what you need to do is to calculate the width that the text should take and then compare with the input width. You can check this link for some idea Calculating text width

$('.Input input').on('keypress change keyup', function() {
  if ($(this).val().length > 10) {
    $(this).parent().find('.grad').css('opacity', '1');
  } else {
    $(this).parent().find('.grad').css('opacity', '0');
  }
})
$('.Input .grad').click(function() {
  $(this).parent().find('input').focus();
}) 
.Input {
  position: relative;
  width: 100%;
  border: none;
  width: 200px;
}

.grad {
  position: absolute;
  cursor: text;
  top: 25px;
  bottom: 2px;
  left: 0;
  right: 90%;
  opacity: 0;
  transition: 0.5s;
  z-index: 1;
  background-image: linear-gradient(to right, rgba(255, 255, 255, 0.8), transparent);
}
.Input:before {
  content: '';
  position: absolute;
  bottom: 0;
  width: 100%;
  transition: border-bottom 0.5s ease;
  border-bottom: 1px solid gainsboro;
}

.Input input {
  margin-top: 20px;
  height: 40px;
  width: 100%;
  padding-left: 0;
  font-size: 16px;
  font-weight: 300;
  background-color: transparent;
  background-image: linear-gradient(to bottom, gainsboro 50%, tomato 50%);
  background-repeat: no-repeat;
  background-size: 0 11%;
  background-position: 50% 100%;
  transition: all 0.5s ease;
  box-shadow: none;
}

.Input h1 {
  font-size: 16px;
  color: gainsboro;
  font-weight: 400;
  position: absolute;
  pointer-events: none;
  left: 0;
  bottom: 0;
  transition: 0.5s ease all;
  width: 100%;
  line-height: unset;
}

.Input:hover:before {
  transition: border-bottom 0.5s ease;
  border-bottom: 1px solid dimgray;
}

input:focus {
  background-color: transparent;
  background-image: linear-gradient(to bottom, transparent 50%, tomato 50%);
  background-repeat: no-repeat;
  background-size: 100% 11%;
  background-position: 50% 100%;
  transition: all 0.5s ease;
}

input:focus,
input:not(:focus):valid {
  border: none;
  outline: none;
}

input:focus~h1,
input:not(:focus):valid~h1 {
  color: tomato;
  transition: all 0.5s ease;
  transform: translateY(-25px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Input">
  <span class="grad"></span>
  <input type="text" class="Input" name="testInput" value="" data-id="" required>
  <h1>
    MyInput
  </h1>
</div>
<br>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • That's interesting… But what you are doing is to set a white layer over the input; and, what if your input is a component, and you don't want to set the color or this layer, but the transparency of the text? –  Dec 17 '17 at 19:04
  • @NikitaSöze the color of the layer can be changed for white to something transparent also ... but am not sure if we can change the transparency of only a part of the text that's why i choosed a layer over the text to control which part i want to make fade. And we have full control over it to make it like the text is transparent ;) i have updated the layer you can check – Temani Afif Dec 17 '17 at 19:09
  • If I were using a layer I would set the h1 at `z-index: 1` to avoid the layer to overlap the header; but what I want is to set the color (transparent) of the text, because what I'm setting is a component, and it needs to be reusable. –  Dec 17 '17 at 19:12
  • @NikitaSöze yes my first test what an example i didn't pay attention to everything, but we can simply change the position of the layer to make it only go above the text (like you can see now) – Temani Afif Dec 17 '17 at 19:13
  • And then, if you put it above the text, you can not click on it to edit anymore… –  Dec 17 '17 at 22:27
  • @NikitaSöze now you can :) check the update, i also changed the cursor of the layer so we cannot make the difference ;) – Temani Afif Dec 17 '17 at 22:35