So I like Temani Afif's answer about using the clipping mask. Think it's great.
I wanted to propose another solution (a little less elegant). I used Firefox to also test this problem, and clicking outside the text area (losing focus) does not make the 1st digit re-appear or the string go back to normal in the text input there.
I believe the issue is the letter spacing css attribute you set:letter-spacing: 31px;
, and the fact that I believe this would apply to the "blinking" caret that most browsers have. Using Chrome, it seems to remove this when it loses focus, while Firefox retains this even after losing focus.
The 1st solution was to use manually call the blur() function to make the input lose focus. This works in Chrome (using a Self-Executing Anonymous Function):
<input type="text" id="number_text" maxlength="6" onkeyup="(function()
{
var x = document.getElementById('number_text');
let value = x.value
if (value.length >= 6){
x.blur()
return false
}
})();"
pattern="\d{6}" value="1234" >
or even as a Defined Function called by the number_text input like so:
<script>
handleMaxInput = function(){
var x = document.getElementById('number_text');
let value = x.value
if (value.length >= 6){
x.blur()
return false
}
};
</script>
<input ... id='number_text' ... onkeyup="handleMaxInput()" ... >
You will notice a slight delay in Chrome, but calling this in Firefox will not resolve the issue.
We can essentially force this same behavior in Firefox. After some playing around, I figured that Chrome was refreshing/recalculating the letter spacing on a blur. My play session showed that you could force Firefox to recalculate this value programmatically:
- Change the inline style of the input's letter-spacing attribute to a different value (as we cannot edit a CSS class of number_text programmatically without much effort, such as re-writing the entire style tag in the style section of a document).
- Remove the Class number_text from the input.
- 1 and 2 are interchangeable, you need Firefox to fallback to only the inline style you set, without having the class attributes saved 'in memory'.
- Remove the inline-style and reapply the number_text CSS class. This will force the browser to recalculate the letter-seperation as we need it to.
In code, it would look like the following JavaScript function:
handleMaxInput = function(){
var x = document.getElementById('number_text');
let value = x.value
if (value.length >= 6){ // if the input is 6 or more characters
x.classList.remove('number_text') // remove the class
x.style.letterSpacing = '0px' // reset the spacing
setTimeout(function() { // set time to let browser refresh updates
x.classList.add('number_text') // Re-add class after browser refresh
setTimeout(function() { // Remove inline-style after more reculculations
x.style.removeProperty('letter-spacing') // Remove inline style to let class styles apply
x.blur // optional, will force input field to lose focus. Else comment out to avoid that.
}, (1)); // waits 1 millisecond
}, (1)); // waits 1 millisecond
}
}
It will have that same flicker in Firefox as with Chrome, and all shall be well.
Note: The timeout functions are to give the browser time to refresh, and actually update what we need.
Note: You can choose to call .blur() in the function to make the textbox lose focus, or omit that and they will still be in the input field without the error with the digits.
Hope this helps your conceptual understanding, as well as solving the issue. Some other individuals gave good solutions that avoid the whole flicker thing, and work in both Firefox and Chrome!