2
\$\begingroup\$

I want to have a input element for currency where there is a currency icon always at the center (but it adjusts according to the number of digits)

Something like:

enter image description here

This is what I've come up with:

const input = document.querySelector('input');
input.addEventListener('input', resizeInput);
resizeInput.call(input);

function resizeInput() {

  this.style.width = this.value.length + "ch";
}
* {
  font-size: 1.3em;
}

.currency_input {
  width: 10em;
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  display: flex;
  justify-content: center;
  align-items: center;
  border: 2px solid black;
  border-radius: 15px;
}

input {
  min-width: 10%;
  max-width: 80%;
  padding: 0.1em;
  margin: 0.1em;
  border: 0;
}

input:focus,
input:focus {
  outline: none;
}
<div class="currency_input">
  <span> $ </span>
  <input type="text" name="name" autocomplete="off" maxlength="4">
</div>

Is there a better way? Things I haven't taken into considerations? Making it more responsive to be able to resize well? (Of course I will validate input later on)

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I don't understand the units being used. We start out with width: 10em, but then we switch from 10em to NNNch ?!? These are digits, so using ch all the time seems appropriate. And if -ms-transform is to support IE9 or something, we really need a comment explaining the impact and when we can delete such support. A maxlength of 4 is maybe on the small side if people paste in comma / dot punctuation like 1,000.00 or even $1,000.00. Display what was entered, and worry about validating it later. \$\endgroup\$
    – J_H
    Commented Mar 13, 2023 at 0:40
  • \$\begingroup\$ Regarding ch I thought that it meant to have width of a character so I knew that I want the text input to grow by character size every time, and about the -ms-transform: translate(-50%, -50%);, I copied it from somewhere else and I will remove 😅. How would you improve it? \$\endgroup\$
    – pileup
    Commented Mar 13, 2023 at 6:35
  • \$\begingroup\$ I mean how would you make it to act as "one unit" when resizing for example? \$\endgroup\$
    – pileup
    Commented Mar 13, 2023 at 7:04
  • \$\begingroup\$ I think using em (rather than e.g. px) is Good. I think using ch is Good. Both will adjust when user alters the font size. However, they express different things. So use em consistently throughout. Or in this case, given that we're displaying digits, better to use ch throughout. Just don't switch from em to ch is all I was saying. (I anticipate that digits will all render with same width.) \$\endgroup\$
    – J_H
    Commented Mar 13, 2023 at 13:24

2 Answers 2

4
\$\begingroup\$

I think that your solution is pretty good, but, since it's a money input, you should change the input's type to number.

<input type="number" name="name" autocomplete="off" maxlength="4">
\$\endgroup\$
1
\$\begingroup\$

May be something like

.container {
  position: relative;
  height: 100px;
  width: 200px;
  margin: auto;
  border: solid 1px black;
  border-radius: 1em;
  font-size: 1em;
}

.currency_input {
  position: absolute;
  width: 50%;
  top: 50%;
  transform: translate(calc(100% - 0.5em),-50%);
}

input {
  width: 75%;
  border: none;
}

input:focus {
  outline: none;
}
<div class="container">
  <div class="currency_input">
    <span> $ </span>
    <input type="text" name="name" autocomplete="off" maxlength="4">
  </div>
</div>

\$\endgroup\$
1
  • \$\begingroup\$ To me, this is not a code review but an alternative solution that is not within the scope of this platform. \$\endgroup\$
    – tacoshy
    Commented Apr 12, 2023 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.