2

I'm implementing a design where a "fade to black" mask is expected to appear on the left side of the input once the text content reachs the maximum visible width of the input box.

The image bellow illustrates better what I'm trying to acomplish: enter image description here

I already implemented part of it, with the code below:

var input = document.querySelector('#input');
var container = document.querySelector('.myInput');

input.addEventListener('keydown', function(e) {
  if (input.value.length > 12) {
    container.classList.add('faded');
  } else {
    container.classList.remove('faded');
  }
});
body {
  background: #000;
}

.myInput {
  position: relative;
}

.myInput input {
  font-family: "Trim", "NOW G", "Oscine";
  font-style: normal;
  font-weight: 500;
  font-size: 28px;
  background: #000;
  padding: 12px;
  color: #fff;
  box-sizing: border-box;
  margin: 0 0 0 10px;
  border: 1px solid #ccc;
  width: 200px;
}

.faded::before {
  display: block;
  background-image: -webkit-linear-gradient(left, black, rgba(0, 0, 0, 0));
  width: 20px;
  position: absolute;
  content: "";
  left: 15px;
  top: 1px;
  bottom: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="myInput">
  <input id="input" placeholder="Search" />
</div>

My problem now is how to add this mask conditionally (that is, removing the hardcoded 12 chars length and the input hardcoded width) and also, how to create a responsible solution that will work with all widths and all text sizes.

Any ideas?

Tyler Roper
  • 21,445
  • 6
  • 33
  • 56
Guilherme Lemmi
  • 3,271
  • 7
  • 30
  • 30
  • 1
    Not sure if it's an exact dupe but perhaps this is helpful: [Detect if text in an input element exceeds bounds](https://stackoverflow.com/questions/4834445/detect-if-text-in-an-input-type-text-element-exceeds-bounds-in-firefox). It puts the input's text in a placeholder element, fetches the width, and compares it to the input to determine if the text is overflowing or not. – Tyler Roper Jul 24 '19 at 18:23
  • Interesting approach @TylerRoper, I'll give it a try! – Guilherme Lemmi Jul 24 '19 at 18:31

1 Answers1

2

You can find if the input is overflown as

(input.offsetWidth < input.scrollWidth)

Also I'd recommend listening to input event instead of keydown to catch paste as well.

See the snippet below:

document.addEventListener('input', function(e) {
  if (e.target.nodeName.toLowerCase() === 'input') {
    var input = e.target;
    var container = input.parentNode;
    if (input.offsetWidth < input.scrollWidth) {
      if (!container.classList.contains('faded')) {
        container.classList.add('faded');
        var cs = getComputedStyle(input);
        container.querySelector('.shadow').style.left = [
          'border-left-width', 'margin-left', 'padding-left'
        ].reduce(function(a, e) {
          return a += parseInt(cs[e])
        }, 0) + 'px';
      }
    } else {
      container.classList.remove('faded');
    }
  }
});
body {
  background: #000;
}

.myInput {
  position: relative;
  margin:1rem;
}

.myInput input {
  font: normal 500 28px "Trim", "NOW G", "Oscine";
  background: #000;
  padding: 12px;
  color: #fff;
  box-sizing: border-box;
  margin: 0 0 0 10px;
  border: 1px solid #ccc;
  width: 200px;
}

.faded .shadow {
  position: absolute;
  top: 1px;
  bottom: 1px;
  width: 20px;
  background-image: linear-gradient(90deg, #000, rgba(0, 0, 0, 0));
}

#input2 {
  margin-left: 20%;
  padding-left: 3em;
}
<div class="myInput">
  <input id="input" placeholder="Search" />
  <span class="shadow"></span>
</div>


<div class="myInput">
  <input id="input2" placeholder="Search" />
  <span class="shadow"></span>
</div>
Kosh
  • 16,966
  • 2
  • 19
  • 34
  • That's very nice, thanks for your response and for the "input" event tip. However, I'm still having problems to make it work with different input padding values (considering that I'll not know what is the input css beforehand) – Guilherme Lemmi Jul 24 '19 at 19:00
  • @GuilhermeLemmi, your question did not mention any `padding` problems... But I've solved this. See my updated answer. – Kosh Jul 24 '19 at 19:57
  • @GuilhermeLemmi, happy to help. – Kosh Jul 24 '19 at 22:31