What is the method for generating a 4-digit input sequence without the use of JavaScript?

When I enter a four-digit number (verification code) in the form input, the structure of the PIN-code breaks down after entering the fourth digit. The text pointer moves to the fifth character even though I have defined only four characters.

Is there a CSS or JavaScript solution to fix this issue?

.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.net/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.com/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>

Check out the demo on jsfidde

Answer №1

Upon further investigation, I discovered an interesting phenomenon where applying the CSS property overflow: hidden; to the parent element caused the input to shift its position once the fourth value was entered.

Solution:

  • Utilize CSS clip on the <input> element!
  • Set the grid as the background-image of the parent element without using pseudo elements like ::before.

.pinBox {
  --width: 296px;
  --height: 74px;
  --spacing: 47px;
  
  display: inline-block;
  position: relative;
  width: var(--width);
  height: var(--height);
  background-image: url(https://i.sstatic.net/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 autocomplete=off >
</div>

An issue with this approach is that once all four values are inputted and the user clicks after the fourth value, the caret will not be visible as it's clipped within the fifth position. This could lead to a poor user experience in my opinion.

You could potentially enhance this by adding a small JavaScript function that automatically selects all text when the input has reached four characters:

  • If the input length reaches 4 characters, select all text 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.net/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);
}</pre>
<pre><code><div class="pinBox">
  <input class="pinEntry" name="token" type=text maxlength=4 autocomplete=off >
</div>

Another aspect to consider is enhancing accessibility (A11Y) for users with visual impairments. While the design may necessitate removing the CSS outline on the INPUT element, it's crucial to ensure these users can still navigate via tabbing. One solution could involve using separate inputs to gather data which is then consolidated into a hidden field for submission.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Mongoose and Next.js: Encountered Runtime Error - Cannot Access Undefined Properties (Token)

For some reason, the Model I defined is not working properly, despite being similar to another one that works without errors. Can anyone help me figure out why? If you need to see a minimal, reproducible example, check it out here. The problematic code: ...

Ways to determine changes made to a table in MSSQL

What is the most efficient method to determine if a table or row in MSSQL (using Node.js) has been modified? I am looking to verify whether my database has been updated within the past 30 minutes. If no updates have been made in the last half hour, I pla ...

The button's onclick function is not triggering with just one click

I am having trouble with a JavaScript function not being called on the first click. I have to click the button multiple times for it to execute. Here are the methods I have attempted so far: <a href="javascript:delete_todo(4);void(0)"><img border ...

Discovering the reason behind a DOM element's visual alteration upon hovering: Where to start?

Visit this page, then click on the next button to navigate to the time slots section. As you hover over any time slot, you will notice a change in appearance. Despite inspecting Chrome's developer tools, I was unable to locate a style with a hover dec ...

Is it possible for me to adjust the size of the Facebook login button on my website?

I have implemented a Facebook login on my website using the following code: <fb:login-button scope="public_profile,email" onlogin="checkLoginState();"> </fb:login-button> Is it possible to replace this button with a standard button or adjust ...

Problem with Google+ Button Alignment

I arranged my social media buttons in a row - Twitter, Facebook & Google+. The issue is that the Google+ button is not aligning properly. It appears to be spaced out about 3 times further than the Twitter and Facebook buttons. I attempted adjusting the p ...

AngularJS / JQuery - input field with no corresponding label

I am encountering an issue with "Form input without an associated label". This problem is occurring on [textarea], [select], and [input] elements. Below is the code I am using: <div class="panel-body"> <form name="f" data-ng-submit="addTodo()"&g ...

Show XML content in HTML text box

How can I process and display an XML file in a text area without any special formatting? I am exploring different solutions for this task. <?xml version="1.0"?> <phonebooks> <contacts group_name="Sample" editable="1" id="0"> <contact ...

The implementation of display flex is causing issues with the material-ui grid layout

Struggling to implement the grid system from material-ui due to an issue where grid items do not resize when resizing the browser window. The culprit seems to be a parent div with the style property "display": "flex". The dilemma arises from using a mater ...

Are the CSS properties from the parent template automatically applied to the extended child template in Django?

While working on a Django site, I encountered an issue with applying CSS properties to an extended template file. The CSS file was imported in the parent template but the changes were not reflecting in the child template. Here is the snippet of my code: ...

NextJS is like the master of ceremonies in the world of backend

As I was searching for the top JS backend frameworks, I came across NextJS which is considered to be one of the best. Initially, I thought NextJS was just a simplified version of CRA and still required Node.js as the backend. This brought me back to my c ...

The value of React state may be unpredictable, even if it appears to be defined on the

<li className="field-title">Role: </li> {console.log(this.state.userData.roles)} {this.state.userData.roles.map((role) => { return ( <li>{role.name}</li> ) })} Even though when I console log the state ...

Is there a way to adjust the width of the datepicker on my device?

I've been attempting to adjust the width of the date picker, but I'm having trouble achieving it. Below is my code: import React from "react"; import ReactDOM from "react-dom"; import { DatePicker, RangeDatePicker } from &qu ...

Tips for decreasing the placeholder font size within a mobile media query

I'm encountering a strange issue. I successfully managed to decrease the font size of the placeholder text for my desktop design, but it's not working for my mobile phone media query. I started with the desktop version and used a max width of 480 ...

Is there a way to retrieve two distinct values from an object?

Is there a way to retrieve two target values from an option using useState in react/nextjs? Here is a sample of my api: const movies = [ { id: 1, name: "Fight Club" }, { id: 2, name: "Titanic" }, { ...

Trouble with displaying Django for loop in HTML template

Having an issue with displaying the latest post. Here is the code: views.py def latest_post(request): latest = Post.objects.all().order_by('-id')[:1] context = {'latestPost': latest} return render(request, 'latest_pos ...

Which is more efficient: Implementing caching on the frontend or on the

Currently, I am using ajax to send requests to the backend server, where operations are performed and responses are received: function getData() { new Ajax().getResponse() .then(function (response) { // handle response }) .catch(functi ...

Angular displays error ERR_UNKNOWN_URL_SCHEME when attempting to retrieve an image saved in a blob

As I transition my app from Electron to Angular, one of my main objectives is to display an image uploaded by a user. Here's how I attempted to achieve this: page.component.ts uploadImageFile(){ fileDialog({}, files =>{ //Utilizing the fileDi ...

Creating dynamic email templates in Node.js

I am working on a project using the MEAN stack and I need to implement email functionality. I have created separate email templates, but I want to include a common header and footer in all of them. Route.js router .route('/api/user/register&a ...

Obtaining the date for the previous month using JavaScript or jQuery

I need to retrieve a specific date in JavaScript. My goal is to obtain the current date based on a variable named frequency, which can have values of Daily, Weekly, or Monthly. if(frequency=="daily") { date='current_date -2 days'; } e ...