Monospaced Font
The best results I've seen came through using a monospace font:
<input type="text" size="4" style="font-family:monospace" />
Online Example: http://jsbin.com/epagi/edit Rendered neatly in Firefox, Chrome, Safari, and IE.
If you're using a variable-width font, you would have to use scripting to get a better guess as to what the expected width would be, but as you said, this isn't very elegant.
Variable-Width Font
I tried to work up a reasonable-simple solution for variable-width fonts, but ultimately you will need to see if it fits your project or not.
Basically what I did was set the text-transform
of particular inputs to uppercase
to get a semi-consistent expectation for how wide something will be when filled out with text. I then applied a classname that indicated the field should be auto-sized, and how many chars we're expecting: sizeMe-4
. Using jQuery, I collected all of these inputs, and split this classname to get the number of chars expected.
I extended the String object to include a repeat method which allows me to easily create a string of the expected size, and add it to an ad-hoc span element to get the width. This width was then retroactively applied to the initial input element. The span is then discarded.
Online Demo: http://jsbin.com/epagi/2/edit
For convenience, here's the code:
<input type="text" name="pin" maxlength="4" class="sizeMe-4"
style="text-transform:uppercase" />
--
String.prototype.repeat = function(num) {
return new Array( num + 1 ).join( this );
}
$(function(){
$(":input[class^='sizeMe']").each(function(){
var size = Number($(this).attr("class").split("-").pop());
var newW = $("<span>").text( "X".repeat(size) ).appendTo("body");
$(this).width( $(newW).width() );
$(newW).remove();
});
});