I have an input field and maxLength value, I want to divide input field into equal virtual boxes of maxLength so that each box contains a single letter.
For e.g if my maxLength value is 10 and input width is 100px, I want to spread these 10 characters over entire width of input, desired result is as shown below
I decided to calculate letter spacing based on character W (as it is the widest character) using below code and adding css letterSpacing property, but that's not giving me the accurate result
enter code here
function calculateLetterSpacing(fontInfo, width, maxLength) {
const inputWidth = width;
const span = document.createElement('span');
span.innerText = "W";
span.style.fontSize = fontInfo.fontSize;
span.style.fontFamily = fontInfo.fontName;
document.body.appendChild(span);
const charMaxWidth = span.offsetWidth;
return (inputWidth - charMaxWidth*maxLength)/maxLength;
}
Is there any direct css property that can allow me to do that.
P.S font can be anything, it's not monospaced.
There's no direct css property that will do that, but I got your function to work. Click "Run code snippet" at bottom and see comments in code for explanation.
var inputfield = document.getElementById("inputfield"); // the input field
var temp = document.getElementById("temphidden"); // the hidden span
var fontsizeOption = document.getElementById("fontsize"); // dropdown for font-size
var fontnameOption = document.getElementById("fontname"); // dropdown for font-name
var widthOption = document.getElementById("inputwidth"); // dropdown for input field's width
var lengthOption = document.getElementById("maxlength"); // dropdown for maxLength
// for demo purposes get the initial values from the dropdowns
var w = parseInt(widthOption.options[widthOption.selectedIndex].value); // initialize width
var m = parseInt(lengthOption.options[lengthOption.selectedIndex].value); // initialize maxLength
var f = { // initialize the fontInfo object
fontSize : fontsizeOption.options[fontsizeOption.selectedIndex].value,
fontName : fontnameOption.options[fontnameOption.selectedIndex].value
};
calculateLetterSpacing(f, w, m); // initialize the attributes
function calculateLetterSpacing(fontInfo, width, maxLength) {
var inputWidth = width;
// set the width of the input field
inputfield.style.width = inputWidth + "px";
// set the font-size of the input field and in the hidden span
inputfield.style.fontSize = temp.style.fontSize = fontInfo.fontSize;
// set the font name - both locations
inputfield.style.fontFamily = temp.style.fontFamily = fontInfo.fontName;
// set the max number of chars allowed in the input field
inputfield.maxLength = maxLength;
// copy the content of input field into the hidden span
temp.innerHTML = inputfield.value;
// the hidden span's size grows as each character is typed in,
// therefore the width in pixels of the span == width in pixels
// of the input string; calculate whiteSpace
var whiteSpace = parseInt(inputfield.style.width) - temp.clientWidth;
// before text is typed in the length is 0, so check for this
if (temp.innerHTML.length == 0) { return; }
// divide whiteSpace by numChars to get the amount of letter-spacing
inputfield.style.letterSpacing = (whiteSpace / temp.innerHTML.length) + "px";
// focus back to the input field
inputfield.focus();
}
body {font:14px arial;text-align:center;}
#inputfield {
padding-left:1px;
text-align:center;
display:block;
margin:0 auto 20px auto;
line-height:30px;
}
.selectwrapper { /* select boxes are for example purposes */
display:block;
margin:10px auto;
width:110px;
}
.selectwrapper select {
width:100%;
font:18px arial;
height:30px;
}
<!-- The input field -->
<p>Type something in ...</p>
<input id="inputfield" type="text" onkeyup="calculateLetterSpacing(f, w, m)">
<!-- The span below is hidden. When a character is entered, it is also copied to this
hidden span ("temphidden"). The span's growing width provides the width in
pixels of the character string regardless of the font type or size. Access the
width of the hidden span using [element].clientWidth -->
<span id="temphidden" style="position:absolute;visibility:hidden;white-space:nowrap;padding:1px;"></span>
<!-- The dropdowns are for demonstration purposes, see "Run code snippet" -->
<div class="selectwrapper">font-size
<select id="fontsize" onchange="{f.fontSize=this.value; calculateLetterSpacing(f, w, m)}">
<option value="8px">8px</option>
<option value="12px" selected="selected">12px</option>
<option value="18px">18px</option>
<option value="24px">24px</option>
</select>
</div>
<div class="selectwrapper">font name
<select id="fontname" onchange="{f.fontName=this.value; calculateLetterSpacing(f, w, m)}">
<option value="times">Times</option>
<option value="arial" selected="selected">Arial</option>
<option value="Verdana">Verdana</option>
<option value="Courier">Courier</option>
</select>
</div>
<div class="selectwrapper">width
<select id="inputwidth" onchange="{w=this.value; calculateLetterSpacing(f, w, m)}">
<option value="80">80px</option>
<option value="100" selected="selected">100px</option>
<option value="150">150px</option>
<option value="220">220px</option>
</select>
</div>
<div class="selectwrapper">max length
<select id="maxlength" onchange="{m=this.value; calculateLetterSpacing(f, w, m)}">
<option value="7">7</option>
<option value="10" selected="selected">10</option>
<option value="15">15</option>
<option value="24">24</option>
</select>
</div>
This is a simpler solution that works perfectly, just tested it. Let flexbox do the work for you, it is a CSS tool as you asked. Paste this in a HTML file and save and open in your browser, it will space however many letters you put into the word variable equally across the screen
let lettersHTML = "";
//define the word
let word = "thing";
//split it
let split = word.split('');
//this splits your word into ["t","h","i","n","g"]
//iterate with for loop - over each letter
for (let i=0; i<split.length; i++) {
let para = document.createElement("P");
para.innerHTML = `${split[i]}`;
document.getElementById("container").appendChild(para);
}
#container {
margin: 0;
padding: 0;
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
<!DOCTYPE html>
<html>
<body>
<div id="container">
</div>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With