最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

html - How to create a 4 digit input series without JavaScript? - Stack Overflow

matteradmin8PV0评论

I have a form input in which I want to enter a four-digit number (verification code). My problem is that after entering the fourth number, the structure and order of the PIN-code breaks down. Because the text pointer goes to the fifth character while I have defined four characters.

Is there a way to solve this problem with pure CSS? Or at least with pure JavaScript?

.pinBox {
  display: inline-block;
  overflow: hidden;
  position: relative;
  direction: ltr;
  text-align: left;
}

.pinBox:before {
  position: absolute;
  left: 0;
  right: 0;
  content: '';
  pointer-events: none;
  display: block;
  height: 75px;
  width: 300px;
  background-image: url(.png);
}

.pinEntry {
  position: relative;
  padding: 16px 29px;
  font-family: courier, monospaced;
  font-size: xx-large;
  border: none;
  outline: none;
  width: 302px;
  letter-spacing: 55px;
  background-color: transparent;
  overflow: hidden;
  text-align: left;
  direction: ltr;
}
<link rel="stylesheet" type="text/css" href=".0.1/css/bootstrap.css"/>

<form role="form" method="POST" action="">
  <div class="row my-4">
    <div class="col-12 text-center">
      <div class="pinBox">
        <input class="pinEntry" name="token" type="text" maxlength="4" value="">
      </div>
    </div>
  </div>

  <div class="text-center">
    <button type="submit" class="btn btn-primary mt-2">submit</button>
  </div>
</form>

I have a form input in which I want to enter a four-digit number (verification code). My problem is that after entering the fourth number, the structure and order of the PIN-code breaks down. Because the text pointer goes to the fifth character while I have defined four characters.

Is there a way to solve this problem with pure CSS? Or at least with pure JavaScript?

.pinBox {
  display: inline-block;
  overflow: hidden;
  position: relative;
  direction: ltr;
  text-align: left;
}

.pinBox:before {
  position: absolute;
  left: 0;
  right: 0;
  content: '';
  pointer-events: none;
  display: block;
  height: 75px;
  width: 300px;
  background-image: url(https://i.sstatic/JbkZl.png);
}

.pinEntry {
  position: relative;
  padding: 16px 29px;
  font-family: courier, monospaced;
  font-size: xx-large;
  border: none;
  outline: none;
  width: 302px;
  letter-spacing: 55px;
  background-color: transparent;
  overflow: hidden;
  text-align: left;
  direction: ltr;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare./ajax/libs/twitter-bootstrap/5.0.1/css/bootstrap.css"/>

<form role="form" method="POST" action="">
  <div class="row my-4">
    <div class="col-12 text-center">
      <div class="pinBox">
        <input class="pinEntry" name="token" type="text" maxlength="4" value="">
      </div>
    </div>
  </div>

  <div class="text-center">
    <button type="submit" class="btn btn-primary mt-2">submit</button>
  </div>
</form>

here is a jsfidde demo

Share Improve this question edited Mar 6, 2022 at 19:16 isherwood 61.2k16 gold badges122 silver badges170 bronze badges asked Mar 6, 2022 at 17:36 user2726957user2726957 1793 silver badges14 bronze badges 2
  • Does this answer your question? CSS: Create iOS style Pin Password box – pilchard Commented Mar 6, 2022 at 17:47
  • 1 @pilchard thanks for the ment. It used several inputs ... my code has only one input so this is not my answer. – user2726957 Commented Mar 6, 2022 at 17:57
Add a ment  | 

1 Answer 1

Reset to default 6

After a bit of investigating I realized that strangely, by assigning overflow: hidden; to the parent element resulted in the input to hop/move contextual X position as soon the 4th value was inserted.

Solution:

  • Use CSS clip on the <input> element!
  • Assign the squared grid as the background-image of your parent element (no need to use ::before pseudo elements!)

.pinBox {
  --width: 296px;
  --height: 74px;
  --spacing: 47px;
  
  display: inline-block;
  position: relative;
  width: var(--width);
  height: var(--height);
  background-image: url(https://i.sstatic/JbkZl.png); 
}

.pinEntry {
  position: absolute;
  padding-left: 21px;
  font-family: courier, monospaced;
  font-size: var(--spacing);
  height: var(--height);
  letter-spacing: var(--spacing);
  background-color: transparent;
  border: 0;
  outline: none;
  clip: rect(0px, calc(var(--width) - 21px), var(--height), 0px);
}
<div class="pinBox">
  <input class="pinEntry" name="token" type=text maxlength=4 autoplete=off >
</div>

One cons of the above is that: once all four values are inputted, and if the user clicks after the fourth value - the caret will not be visible since it's clipped (letter-spaced inside the 5th position). It you can live with it - good, but it's a bad UX/UI in my opinion.

Perhaps you can add to the above some really small JS that does:

  • IF the input has 4 values length - select all the text-value using myInput.select()

Example:

const ELS_pinEntry = document.querySelectorAll(".pinEntry");
const selectAllIfFull = (evt) => {
  const EL_input = evt.currentTarget;
  if (EL_input.value.length >= 4) EL_input.select();
};
ELS_pinEntry.forEach(el => {
  el.addEventListener("focusin", selectAllIfFull);
});
.pinBox {
  --width: 296px;
  --height: 74px;
  --spacing: 47px;
  
  display: inline-block;
  position: relative;
  width: var(--width);
  height: var(--height);
  background-image: url(https://i.sstatic/JbkZl.png); 
}

.pinEntry {
  position: absolute;
  padding-left: 21px;
  font-family: courier, monospaced;
  font-size: var(--spacing);
  height: var(--height);
  letter-spacing: var(--spacing);
  background-color: transparent;
  border: 0;
  outline: none;
  clip: rect(0px, calc(var(--width) - 21px), var(--height), 0px);
}
<div class="pinBox">
  <input class="pinEntry" name="token" type=text maxlength=4 autoplete=off >
</div>

Another cons I would improve by using the above (and the original) idea is: A11Y (Accessibility).
The many users with bad or challenged sight should be able to see an input outline while they tab trough a website. For design reasons the above had to remove the CSS outline on the INPUT element. Which is a no-no.

Currently I have no other better/simpler idea but to use 4 different inputs and join their values into a single hidden one that will ultimately be submitted with the FORM.

Post a comment

comment list (0)

  1. No comments so far