Similar to the below JSFiddle (which I bookmarked and do not know from where the original question emerged):
http://jsfiddle.net/mJMpw/6/
UPDATED[2]:
As scrollHeight
is always equal to height
, we have to set height to '1' before scrollHeight, then when we delete characters the <textarea>
autofit:
$('textarea').on('keydown', function(e){
if(e.which == 13) {e.preventDefault();}
}).on('input', function(){
$(this).height(1);
var totalHeight = $(this).prop('scrollHeight') - parseInt($(this).css('padding-top')) - parseInt($(this).css('padding-bottom'));
$(this).height(totalHeight);
});
Fiddle:
http://jsfiddle.net/mJMpw/551/
UPDATED:
As friends said, <input type="text"/>
has no line breaks. My suggest using <textarea>
is:
$('textarea').on({input: function(){
var totalHeight = $(this).prop('scrollHeight') - parseInt($(this).css('padding-top')) - parseInt($(this).css('padding-bottom'));
$(this).css({'height':totalHeight});
}
});
Fiddle:
http://jsfiddle.net/mJMpw/548/
ORIGINAL ANSWER:
this is very ugly but you could do it like this:
$('input[type="text"]').on('keyup',function(){
var text = $(this).val();
var getWidth = $('<span class="getWidth" style="white-space:nowrap; width:auto;">' + text + '</span>').insertAfter(this);
$(this).css({'width':getWidth.outerWidth()}).next('.getWidth').remove();
});
You have to specify the same fonts/padding property to .getWidth and you input:
input, .getWidth {
font-family:arial;
font-size:12px;
font-weight:normal;
letter-spacing:normal;
padding:3px;
}
Fiddle:
http://jsfiddle.net/9SMRf/
Not mine but works great:
CSS
textarea {
color: #444;
padding: 5px;
}
.txtstuff {
resize: none;
overflow: hidden;
}
.hiddendiv {
display: none;
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: break-word
}
.common {
width: 500px;
min-height: 50px;
font-family: Arial, sans-serif;
font-size: 13px;
overflow: hidden;
}
.lbr {
line-height: 3px;
}
HTML
<textarea id="comments" placeholder="Type many lines of texts in here and you will see magic stuff" class="common"></textarea>
SCRIPT
let txt = $('#comments'),
txt.addClass('txtstuff');
let hiddenDiv = $(document.createElement('div')),
hiddenDiv.addClass('hiddendiv common');
let content = null;
$('body').append(hiddenDiv);
txt.on('keyup', function () {
content = $(this).val();
content = content.replace(/\n/g, '<br>');
hiddenDiv.html(content + '<br class="lbr">');
$(this).css('height', hiddenDiv.height());
});
FIDDLE
As others explained, input
field can't have multiline text, you should use textarea
to mimic an input field, and jQuery to make it auto resize vertically (with fixed width).
JS:
//This span is used to measure the size of the textarea
//it should have the same font and text with the textarea and should be hidden
var span = $('<span>').css('display','inline-block')
.css('word-break','break-all')
.appendTo('body').css('visibility','hidden');
function initSpan(textarea){
span.text(textarea.text())
.width(textarea.width())
.css('font',textarea.css('font'));
}
$('textarea').on({
input: function(){
var text = $(this).val();
span.text(text);
$(this).height(text ? span.height() : '1.1em');
},
focus: function(){
initSpan($(this));
},
keypress: function(e){
//cancel the Enter keystroke, otherwise a new line will be created
//This ensures the correct behavior when user types Enter
//into an input field
if(e.which == 13) e.preventDefault();
}
});
CSS:
textarea {
width:200px;
resize:none;
overflow:hidden;
font-size:18px;
height:1.1em;
padding:2px;
}
This new updated demo has some bugs fixed and it also supports Enter key, max-height limit, the width does not need to be set fixedly at first (instead we can set its min-width). It's much more full-featured.