to the width of the actual value...">

Automatically scale input [type = text] to a width value?

Is there a way to scale the width of <input type="text"> to the width of the actual value?

 input { display: block; margin: 20px; width: auto; } 
 <input type="text" value="I've had enough of these damn snakes, on this damn plane!" /> <input type="text" value="me too" /> 
+68
jquery html css
Nov 11 2018-11-11T00:
source share
15 answers

You can do this in a simple way by setting the size attribute to the length of the input content:

 function resizeInput() { $(this).attr('size', $(this).val().length); } $('input[type="text"]') // event handler .keyup(resizeInput) // resize on page load .each(resizeInput); 

See: http://jsfiddle.net/nrabinowitz/NvynC/

It seems that adding some add-ons on the right, which I suspect is browser dependent. If you want it to be very dense for input, you can use a technique like the one I describe in this related answer , using jQuery to calculate the pixel size of your text.

+73
Nov 11 2018-11-11T00:
source share

If for some reason other solutions do not work for you, you can use contenteditable-span instead of the input element.

 <span contenteditable="true">dummy text</span> 

Note that this is more of a hack and has a serious flaw that allows for completely non-anonymous HTML input, allowing users to enter (and insert) lines, links and other HTML.

So, you probably shouldn't use this solution unless you sanitize the entrance very carefully ...

Update : you probably want to use the Obsidian solution below .

+33
Feb 25 '13 at 12:07 on
source share

SIMPLICITY BUT PIXEL PERFECT SOLUTION

I saw several ways to do this, but calculating the width of the fonts is not always 100% accurate, it's just an estimate.

I managed to create the perfect pixel way to adjust the input width using a hidden replacement object.




jQuery (recommended)

  $(function() { . $( '# ')  ($ ( '# TXT') ().); . $( '# TXT')  ($ ( '# ') ().); }). on ('input', function() { . $( '# ')  ($ ( '# TXT') ().); . $( '# TXT')  ($ ( '# ') ().); });> 
  body, #, #{ : ; : 0; : 0; } #{ : ; : # 888; -: 10px; } #{ : ; -: ; }> 
  < script src= "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery. min.js" > < &/; GT <p> Lorem ipsum < span id = "hide" > </span> < input id = "txt" type = "text" value = "type here..." > egestas arcu. </ >> 



Pure javascript

I was not able to determine how jQuery calculates the width of the hidden elements, so posting this solution requires a small change in css.

  var hide = document.getElementById('hide'); var txt = document.getElementById('txt'); (); txt.addEventListener( "enter",  ); function resize() { hide.textContent = txt.value; txt.style.width = hide.offsetWidth + "px"; }> 
  body, #, # { font: inherit; margin: 0; : 0; } # { border: none; : # 888; -: 10 ; } # { : ; : 0; : ; white-space: pre; }> 
  <p> Lorem ipsum < span id = "hide" > </span> < input id = "txt" type = "text" value = "type here..." > egestas arcu. </ >> 
+10
Aug 10 '16 at 7:49
source share

Change Now the plugin works with trailing whitespace. Thanks for pointing out @JavaSpyder

Since most of the other answers didn't match what I needed (or just didn't work at all) I changed Adrian B's answer to the correct jQuery plugin, which leads to perfect input scaling in pixels without the need to change your css or html.

Example: https://jsfiddle.net/587aapc2/

Usage: $("input").autoresize({padding: 20, minWidth: 20, maxWidth: 300});

Plugin:

 //JQuery plugin: $.fn.textWidth = function(_text, _font){//get width of text with font. usage: $("div").textWidth(); var fakeEl = $('<span>').hide().appendTo(document.body).text(_text || this.val() || this.text()).css({font: _font || this.css('font'), whiteSpace: "pre"}), width = fakeEl.width(); fakeEl.remove(); return width; }; $.fn.autoresize = function(options){//resizes elements based on content size. usage: $('input').autoresize({padding:10,minWidth:0,maxWidth:100}); options = $.extend({padding:10,minWidth:0,maxWidth:10000}, options||{}); $(this).on('input', function() { $(this).css('width', Math.min(options.maxWidth,Math.max(options.minWidth,$(this).textWidth() + options.padding))); }).trigger('input'); return this; } //have <input> resize automatically $("input").autoresize({padding:20,minWidth:40,maxWidth:300}); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input value="i magically resize"> <br/><br/> called with: $("input").autoresize({padding: 20, minWidth: 40, maxWidth: 300}); 
+9
Dec 11 '15 at 13:20
source share

I have a jQuery plugin on GitHub: https://github.com/MartinF/jQuery.Autosize.Input

It reflects the input value, calculates the width, and uses it to set the input width.

Here you can see a live example: http://jsfiddle.net/mJMpw/2175/

An example of how to use it (since some code is needed when sending the jsfiddle link):

 <input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 40 }' /> input[type="data-autosize-input"] { width: 90px; min-width: 90px; max-width: 300px; transition: width 0.25s; } 

You just use css to set min / max-width and use the width transition if you want a nice effect.

You can specify a space / distance to the end as a value in json notation for the input-autosize-input attribute on the input element.

Of course you can just initialize it with jQuery

 $("selector").autosizeInput(); 
+6
Jun 13 '13 at 23:31
source share

There are already many good answers. For fun, I implemented this solution below, based on other answers and my own ideas.

 <input class="adjust"> 

The input element is fine-tuned and an additional offset can be determined.

 function adjust(elements, offset, min, max) { // Initialize parameters offset = offset || 0; min = min || 0; max = max || Infinity; elements.each(function() { var element = $(this); // Add element to measure pixel length of text var id = btoa(Math.floor(Math.random() * Math.pow(2, 64))); var tag = $('<span id="' + id + '">' + element.val() + '</span>').css({ 'display': 'none', 'font-family': element.css('font-family'), 'font-size': element.css('font-size'), }).appendTo('body'); // Adjust element width on keydown function update() { // Give browser time to add current letter setTimeout(function() { // Prevent whitespace from being collapsed tag.html(element.val().replace(/ /g, '&nbsp')); // Clamp length and prevent text from scrolling var size = Math.max(min, Math.min(max, tag.width() + offset)); if (size < max) element.scrollLeft(0); // Apply width to element element.width(size); }, 0); }; update(); element.keydown(update); }); } // Apply to our element adjust($('.adjust'), 10, 100, 500); 

Customization is smoothed using a CSS transition.

 .adjust { transition: width .15s; } 

Here is the fiddle . Hope this helps others looking for a clean solution.

+5
Mar 15 '14 at 11:30
source share

You can solve this problem like here :) http://jsfiddle.net/MqM76/217/

HTML:

 <input id="inpt" type="text" /> <div id="inpt-width"></div> 

JS:

 $.fn.textWidth = function(text, font) { if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body); $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font')); return $.fn.textWidth.fakeEl.width(); }; $('#inpt').on('input', function() { var padding = 10; //Works as a minimum width var valWidth = ($(this).textWidth() + padding) + 'px'; $('#'+this.id+'-width').html(valWidth); $('#inpt').css('width', valWidth); }).trigger('input'); 
+3
Jun 04 '14 at 18:42
source share

Unfortunately, the size attribute will not work very well. Sometimes there will be extra space and too little space, depending on the font settings. (see example)

If you want this to work well, try looking at the input changes and then resize it. You probably want to set it to scrollWidth input. We will also need to consider the size of the window.

In the following example, I set the input size to 1 so that it does not have scrollWidth that is larger than our initial width (set manually using CSS).

 // (no-jquery document.ready) function onReady(f) { "complete" === document.readyState ? f() : setTimeout(onReady, 10, f); } onReady(function() { [].forEach.call( document.querySelectorAll("input[type='text'].autoresize"), registerInput ); }); function registerInput(el) { el.size = 1; var style = el.currentStyle || window.getComputedStyle(el), borderBox = style.boxSizing === "border-box", boxSizing = borderBox ? parseInt(style.borderRightWidth, 10) + parseInt(style.borderLeftWidth, 10) : 0; if ("onpropertychange" in el) { // IE el.onpropertychange = adjust; } else if ("oninput" in el) { el.oninput = adjust; } adjust(); function adjust() { // reset to smaller size (for if text deleted) el.style.width = ""; // getting the scrollWidth should trigger a reflow // and give you what the width would be in px if // original style, less any box-sizing var newWidth = el.scrollWidth + boxSizing; // so let set this to the new width! el.style.width = newWidth + "px"; } } 
 * { font-family: sans-serif; } input.autoresize { width: 125px; min-width: 125px; max-width: 400px; } input[type='text'] { box-sizing: border-box; padding: 4px 8px; border-radius: 4px; border: 1px solid #ccc; margin-bottom: 10px; } 
 <label> Resizes: <input class="autoresize" placeholder="this will resize" type='text'> </label> <br/> <label> Doesn't resize: <input placeholder="this will not" type='text'> </label> <br/> <label> Has extra space to right: <input value="123456789" size="9" type="text"/> </label> 

I think this should work even in IE6, but don't take my word for it.

Depending on your use case, you may need to bind the configuration function to other events. For example. by changing the input value programmatically or by changing the display style property from none (where scrollWidth === 0 ) to block or inline-block , etc.

+3
Sep 26 '16 at 22:00
source share

Instead of trying to create a div and measure its width, I think it is more reliable to measure the width directly with the canvas element, which is more accurate.

 function measureTextWidth(txt, font) { var element = document.createElement('canvas'); var context = element.getContext("2d"); context.font = font; return context.measureText(txt).width; } 

Now you can use this to measure how wide an input element should be at any given time by doing this:

 // assuming inputElement is a reference to an input element (DOM, not jQuery) var style = window.getComputedStyle(inputElement, null); var text = inputElement.value || inputElement.placeholder; var width = measureTextWidth(text, style.font); 

This returns a number (possibly a floating point). If you want to consider registration, you can try the following:

  var desiredWidth = (parseInt(style.borderLeftWidth) + parseInt(style.paddingLeft) + Math.ceil(width) + 1 + // extra space for cursor parseInt(style.paddingRight) + parseInt(style.borderRightWidth)) inputElement.style.width = desiredWidth + "px"; 
+3
Apr 19 '17 at 7:12
source share

My jQuery plugin works for me:

Using:

  $('form input[type="text"]').autoFit({ }); 

jquery.auto-fit.js Source jquery.auto-fit.js :

 ; (function ($) { var methods = { init: function (options) { var settings = $.extend(true, {}, $.fn.autoFit.defaults, options); var $this = $(this); $this.keydown(methods.fit); methods.fit.call(this, null); return $this; }, fit: function (event) { var $this = $(this); var val = $this.val().replace(' ', '-'); var fontSize = $this.css('font-size'); var padding = $this.outerWidth() - $this.width(); var contentWidth = $('<span style="font-size: ' + fontSize + '; padding: 0 ' + padding / 2 + 'px; display: inline-block; position: absolute; visibility: hidden;">' + val + '</span>').insertAfter($this).outerWidth(); $this.width((contentWidth + padding) + 'px'); return $this; } }; $.fn.autoFit = function (options) { if (typeof options == 'string' && methods[options] && typeof methods[options] === 'function') { return methods[options].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof options === 'object' || !options) { // Default to 'init' return this.each(function (i, element) { methods.init.apply(this, [options]); }); } else { $.error('Method ' + options + ' does not exist on jquery.auto-fit.'); return null; } }; $.fn.autoFit.defaults = {}; })(this['jQuery']); 
+1
Mar 03 '15 at 11:55
source share

Input elements behave differently than other elements that will do what you need if you give them float: left (see http://jsfiddle.net/hEvYj/5/ ). I don't think this is possible without calculating it in any way using JavaScript (i.e. add 5px to the width of the letter in the box).

0
Nov 11 '11 at 10:40
source share

The user solution nrabinowitz works fine, but I use the keypress event instead of keyup . This reduces latency if the user slowly enters data.

0
Aug 15 '13 at 14:51
source share

Here is my modification of the nrabinowitz solution. I did not use the size property because it is not perfect with proportional fonts, as @Mark noted. My solution puts the element after input and gets the width calculated by the browser (using jQuery).

Although I am not testing it, I believe that it will work only if all CSS properties affecting the font are inherited.

The width of the input signal changes to a focusout event, which works better for me. But you can use keyup / keypress to change the input width as you type.

 function resizeInput() { //Firstly take the content or placeholder if content is missing. var content = $(this).val().length > 0 ? $(this).val() : $(this).prop("placeholder"); //Create testing element with same content as input. var widthTester = $("<span>"+content+"</span>").hide(); //Place testing element into DOM after input (so it inherits same formatting as input does). widthTester.insertAfter($(this)); //Set inputs width; you may want to use outerWidth() or innerWidth() //depending whether you want to count padding and border or not. $(this).css("width",widthTester.width()+"px"); //Remove the element from the DOM widthTester.remove(); } $('.resizing-input').focusout(resizeInput).each(resizeInput); 
0
Mar 06 '14 at 14:12
source share

Using the canvas, we can calculate the width of the elements:

 function getTextWidth(text, fontSize, fontName) { let canvas = document.createElement('canvas'); let context = canvas.getContext('2d'); context.font = fontSize + fontName; return context.measureText(text).width; } 

and use it for the selected event:

 function onChange(e) { let width = getTextWidth(this.value, $(this).css('font-size'), $(this).css('font-family')); $(this.input).css('width', width); } 
0
May 11 '17 at
source share

try canvas measureText solution

CSS

  input{ min-width:10px!important; max-width:99.99%!important; transition: width 0.1s; border-width:1px; } 

JavaScript:

 function getWidthOfInput(input){ var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var text = input.value.length ? input.value : input.placeholder; var style = window.getComputedStyle(input); ctx.lineWidth = 1; ctx.font = style.font; var text_width = ctx.measureText(text).width; return text_width; } function resizable (el, factor) { function resize() { var width = getWidthOfInput(el); el.style.width = width + 'px'; } var e = 'keyup,keypress,focus,blur,change'.split(','); for (var i in e){ el.addEventListener(e[i],resize,false); } resize(); } $( "input" ).each( function(i){ resizable(this); }); 
0
Nov 29 '17 at 12:42 on
source share



All Articles