32

Is there anyway through CSS or Javascript set the height of the textarea based on the content? I have a hardcoded height in my CSS but i wanted it to default so there is no vertical scroll bar on page load?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
leora
  • 188,729
  • 360
  • 878
  • 1,366

14 Answers14

20

How about http://www.jacklmoore.com/autosize/ Drop Autosize into any web page and it should Just Work. The source is short and well commented if you are curious to how it works.

// Example:
$(document).ready(function(){
    $('textarea').autosize();   
});

Source: https://github.com/jackmoore/autosize

Demo: http://www.jacklmoore.com/autosize/

MK.
  • 5,139
  • 1
  • 22
  • 36
  • This is not just at page load: it is dynamic (although it is probably possible to get the effect with this plugin). Dynamic was asked at: http://stackoverflow.com/questions/454202/creating-a-textarea-with-auto-resize/25566909#25566909 – Ciro Santilli OurBigBook.com Aug 29 '14 at 11:05
  • In case anyone is having trouble installing Autosize, the important javascript is at https://raw.githubusercontent.com/jackmoore/autosize/master/dist/autosize.js. Once you've included that script in your project, you then simply include this line of javascript in your project too: autosize(document.querySelectorAll('textarea')) – Paul Chris Jones Mar 04 '20 at 11:45
  • Nice clean script, easy to use, highly recommended! – John Contarino Aug 28 '20 at 15:52
8

You can use the auto resize plugin using the jQuery UI Autoresize

Here is the html,

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script
 src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script src="http://css-tricks.com/examples/TextareaTricks/js/autoresize.jquery.min.js"></script>
<textarea></textarea>

and here is the jquery,

$('textarea').autoResize();

see DEMO

mcn
  • 711
  • 4
  • 9
  • 1
    Maybe add a `$('textarea').change()` to trigger the resize on page load? Question wanted there to be no vertical scroll bar on page load, which perhaps implies that the textarea maybe filled beforehand. – mfirdaus May 27 '14 at 16:24
8

Without plugins you could do something like

$(document).ready(function(){
  elem=document.getElementById('#elemid');
  while(elem.clientHeight < elem.scrollHeight) {elem.height(elem.height()+10)}
});

Resizing the textarea while it does have a scrollbar (so elem.clientHeight < elem.scrollHeight). You can do it quite easily even without JQuery, in plain javascript.

Didn't test the code, it's just the "concept".

EDIT: Dumb me, it's much easier, no loops...

if (elem.clientHeight < elem.scrollHeight) elem.style.height=elem.scrollHeight+"px";
miguel-svq
  • 2,136
  • 9
  • 11
3

Tested in chrome

Pure javascript solution (No plugin, No jquery)

in action: fiddle

I created 3 functions:

  • get line height
  • get number of lines
  • set the height of textarea as you type (input event)

    //attach input event
    document.getElementById('ta').addEventListener('input', autoHeight, false);

    function autoHeight(e){
        var lh = getLineHeightInPixels(e.target);
        var nol = getNumberOfLines(e.target);
        var ht = lh * nol;
        e.target.style.height = ht + 'px';
    }

    function getNumberOfLines(el){
        var text = el.value
        var lines = text.split(/\r|\r\n|\n/);
        return lines.length;
    }

    function getLineHeightInPixels(el){

        var tempDiv = document.createElement('div');

        tempDiv.style.visibility = 'hidden';

        tempDiv.style.fontFamily = getComputedStyle(el).getPropertyValue('font-family');
        tempDiv.style.fontSize = getComputedStyle(el).getPropertyValue('font-size');
        tempDiv.style.lineHeight = getComputedStyle(el).getPropertyValue('line-height');
        tempDiv.style.fontVariant = getComputedStyle(el).getPropertyValue('font-variant');
        tempDiv.style.fontStyle = getComputedStyle(el).getPropertyValue('font-style');

        tempDiv.innerText = 'abcdefghijklmnopqrstuwxyz';

        document.documentElement.appendChild(tempDiv);

        var ht = parseInt(getComputedStyle(tempDiv).getPropertyValue('height'))

        document.documentElement.removeChild(tempDiv);
        return (ht);
    }

    //set height on document load
    document.addEventListener('DOMContentLoaded', function(){document.getElementById('ta').style.height = getLineHeightInPixels(document.getElementById('ta')) + 'px';}, false);
<textarea id="ta"></textarea>
LWC
  • 1,084
  • 1
  • 10
  • 28
Amro
  • 1,644
  • 1
  • 11
  • 13
3

This other question about WhatsApp like input has been incorrectly marked as a duplicate of this current question. As I cannot answer there, I'm answering it here.

I was trying to create a WhatsApp like input area, with the following features:

  1. The div/textarea should expand upwards when the content exceeds 4em
  2. Max height of the div/textarea should be 6em
  3. The messaging area (above the div/textarea) should reduce i.e. its scrollbar thumbtack size should change.

Here is my pure CSS solution, if anyone is looking for it (like I was a few minutes ago).

.arena {
  position: absolute;
  height: 20em;
  width: 12em;
  background-color: #efefef;
  padding: 1em;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.messages {
  padding: 0.2em;
  height: 5em;
  flex: 1 1 0;
  overflow: auto;
}
.content {
  background-color: teal;  
  height: 20em;
}
.footer {
  position: relative;
  background-color: #cdcdcd;
  padding: 0.2em;
}
.editable {
  outline: none;
  max-height: 6em;
  min-height: 4em;
  overflow: auto;
  width: 80%;
  background-color: #fff;
}
<div class="arena">
  <div class="messages">
    <div class="content"></div>
  </div>
  <div class="footer">
    <div class="editable" contenteditable="true"></div>
  </div>
</div>
Kaya Toast
  • 5,267
  • 8
  • 35
  • 59
2

A nice solution

JSFiddle

HTML

<div id="container">
    <textarea >
    1
    12
    123
    1234
    12345
    123456
    1234567
    </textarea>
</div>

CSS

div#container textarea {
    overflow-y: hidden; /* prevents scroll bar flash */
    padding-top: 1.1em; /* prevents text jump on Enter keypress */
}

JQuery

// auto adjust the height of
$('#container').on( 'keyup', 'textarea', function (e){
    $(this).css('height', 'auto' );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keyup();
Community
  • 1
  • 1
Itay Gal
  • 10,706
  • 6
  • 36
  • 75
1

Hey can go with ExpandingTextArea plugin in which an invisible clone pre element is maintained behind your textarea. Whenever the height of this pre changes, the textarea is updated.

It is simple just include "expanding.js" and "jQuery" in your page and add class "expanding" to the textarea to which u need to expand.

<script src='expanding.js'></script>
<textarea class='expanding'></textarea>

Follow the link for more details and Demo

Note: It will work on document load for already added texts

Mazzu
  • 2,799
  • 20
  • 30
  • @leora, are you fine with the explanation above. It may be the required one you are searching for. :) – Mazzu Jun 02 '14 at 05:06
1

If you dont mind a scollbar inside the text area you can use

$(document).ready(function(){
    tx = $('#textarea')
    tx.height(tx.prop('scrollHeight'));

})

and here is a Fiddle

another Fiddle this has min and max-width set.

but with plug-ins like auto-size

the height of the text box increases with input.

or you can try this plug-in

Sudheer
  • 2,955
  • 2
  • 21
  • 35
1

The only css I use below on the textarea is its width, there is no need to set an initial height. overflow should not be needed either as the scrollHeight that will be used is:

a measurement of the height of an element's content including content not visible on the screen due to overflow.

scrollHeight :MDN

If you want to work with Internet Explorer though, then it is necessary to use overflow: auto as otherwise IE insists on adding a vertical scrollbar (even though there is nothing to scroll).

Note that the width does not need to be specified either, but it is the property that is most commonly set in relation to this topic.

This is the JavaScript needed:

document.addEventListener("DOMContentLoaded", function(event) {
    var ta = document.getElementById('ta');
    ta.style.height = ta.scrollHeight + 'px';
});

When the DOM has loaded the height of the textarea is set to its scrollHeight.

Here is a complete page for testing:

<!DOCTYPE html>
<html>
<head>
<title>Some Title</title>
<style>
textarea {
    width: 300px;
    overflow: auto;
}
</style>
</head>
<body>
    <textarea id="ta">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</textarea>
<script>
    document.addEventListener("DOMContentLoaded", function(event) {
        var ta = document.getElementById('ta');
        ta.style.height = ta.scrollHeight + 'px';
    });
</script>
</body>
</html>

If required, the code can be applied to all textareas on the page:

document.addEventListener("DOMContentLoaded", function(event) {
    var tas = document.getElementsByTagName('textarea');
    for (var i=0; i < tas.length; i++) {
        tas[i].style.height = tas[i].scrollHeight + 'px';
    }
});
Andy G
  • 19,232
  • 5
  • 47
  • 69
1

Here is a pure javascript solution. No jquery, no plugins, etc.. DEMO

So how does it work? Suppose you have a default font size/line-height/etc. Well your textarea holds around 11 characters per 100px width. If we can keep this in mind then we can use this function.

function textareaSetSize(elem, width)
{
    var length = elem.value.length;
    //about 11 characters per 100 pixels
    var estimatedLines = Math.round(length/(width/100*11));
    //alert('Estimated number of lines: ' + length);
    elem.style.width  = width + 'px';
    elem.rows = estimatedLines;
}

Then..

    var selector = document.getElementsByClassName('textarea');
    for(var i = 0; i < selector.length; i++)
    {
        selector[i].onkeyup = function(){
            textareaSetSize(this, 400);
        };   
    }

html...

<button id="reset">Empty</button>
<textarea class="textarea" id="autosize"></textarea>
<textarea class="textarea" id="autosize2"></textarea>
<textarea class="textarea" id="autosize3"></textarea>
<textarea class="textarea" id="autosize4"></textarea>

runnning it...

textareaSetSize(ta, 500);
textareaSetSize(ta2, 400);
textareaSetSize(ta3, 400);
textareaSetSize(ta4, 400);

This isn't a perfect solution, so if you see an innovation let me know.

kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131
0

I don't know why, but it seems my search engine brought me another solution (a "How-To" Tutorial):

http://www.sitepoint.com/build-auto-expanding-textarea-3/

EDIT:

here is the code..

/**
 * TextAreaExpander plugin for jQuery
 * v1.0
 * Expands or contracts a textarea height depending on the
 * quatity of content entered by the user in the box.
 *
 * By Craig Buckler, Optimalworks.net
 *
 * As featured on SitePoint.com:
 * http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/
 *
 * Please use as you wish at your own risk.
 */

/**
 * Usage:
 *
 * From JavaScript, use:
 *     $(<node>).TextAreaExpander(<minHeight>, <maxHeight>);
 *     where:
 *       <node> is the DOM node selector, e.g. "textarea"
 *       <minHeight> is the minimum textarea height in pixels (optional)
 *       <maxHeight> is the maximum textarea height in pixels (optional)
 *
 * Alternatively, in you HTML:
 *     Assign a class of "expand" to any <textarea> tag.
 *     e.g. <textarea name="textarea1" rows="3" cols="40" class="expand"></textarea>
 *
 *     Or assign a class of "expandMIN-MAX" to set the <textarea> minimum and maximum height.
 *     e.g. <textarea name="textarea1" rows="3" cols="40" class="expand50-200"></textarea>
 *     The textarea will use an appropriate height between 50 and 200 pixels.
 */

(function($) {

    // jQuery plugin definition
    $.fn.TextAreaExpander = function(minHeight, maxHeight) {

        var hCheck = !($.browser.msie || $.browser.opera);

        // resize a textarea
        function ResizeTextarea(e) {

            // event or initialize element?
            e = e.target || e;

            // find content length and box width
            var vlen = e.value.length, ewidth = e.offsetWidth;
            if (vlen != e.valLength || ewidth != e.boxWidth) {

                if (hCheck && (vlen < e.valLength || ewidth != e.boxWidth)) e.style.height = "0px";
                var h = Math.max(e.expandMin, Math.min(e.scrollHeight, e.expandMax));

                e.style.overflow = (e.scrollHeight > h ? "auto" : "hidden");
                e.style.height = h + "px";

                e.valLength = vlen;
                e.boxWidth = ewidth;
            }

            return true;
        };

        // initialize
        this.each(function() {

            // is a textarea?
            if (this.nodeName.toLowerCase() != "textarea") return;

            // set height restrictions
            var p = this.className.match(/expand(\d+)\-*(\d+)*/i);
            this.expandMin = minHeight || (p ? parseInt('0'+p[1], 10) : 0);
            this.expandMax = maxHeight || (p ? parseInt('0'+p[2], 10) : 99999);

            // initial resize
            ResizeTextarea(this);

            // zero vertical padding and add events
            if (!this.Initialized) {
                this.Initialized = true;
                $(this).css("padding-top", 0).css("padding-bottom", 0);
                $(this).bind("keyup", ResizeTextarea).bind("focus", ResizeTextarea);
            }
        });

        return this;
    };

})(jQuery);


// initialize all expanding textareas
jQuery(document).ready(function() {
    jQuery("textarea[class*=expand]").TextAreaExpander();
});

I left the comments in the code since it is not my work ;)

jBear Graphics
  • 153
  • 1
  • 7
0

I couldn't use scrollHeightas it return 0 on page load (maybe because my textarea is hidden on load). Probably not nest practice (I am a newby in js) but the only option that worked was to count the number of lines in textarea and get length of the longer line in it. Then set the width and height accordingly.

var elements = document.getElementsByTagName("textarea")
for (var i = 0; i < elements.length; i++) {
    var atagelement = elements[i];
    console.log(atagelement.value);

    var textareasplit =atagelement.value.split(/\r|\r\n|\n/);
    var textareaheight =  textareasplit.length *17  // change 17 according to your needs

    var maxline=0
    for  (var j = 0; j < textareasplit.length; j++){
    var line = textareasplit[j];
    var linelenght= line.length;
        if (maxline < linelenght){
            maxline= linelenght;
        };
    };
    var textareawidth= maxline*10  // change 10 according to your needs
    atagelement.setAttribute('style', "width:" + textareawidth+"px ; height:"+textareaheight+"px");

}

If needed, you can also set max-width (or max-height) like this

    var maxwidth= window.innerWidth *0.8
    console.log(maxwidth)
    atagelement.setAttribute('style', "width:" + textareawidth+"px ; height:"+textareaheight+"px ; max-width:" + maxwidth+ "px");
MagTun
  • 5,619
  • 5
  • 63
  • 104
0

This work for me

$(function(){
    $('body').on('keydown','textarea', function(event) {
        if ($('textarea')[0].clientHeight < $('textarea')[0].scrollHeight)
        {
            $('textarea').css({'height': $('textarea')[0].scrollHeight+"px"});
        }
        else
        {
            // reset height to default value
            $('textarea').css({'height': ''});
        }
    });
});
Mohamad Hamouday
  • 2,070
  • 23
  • 20
0

I did it using 1 simple JavaScript function and a 2 CSS class.

<style>
    textarea{
     height: auto;
     resize: none;
     overflow: auto;
    }

    .disabled-input{
     min-height: 4em;
     }
</style>

<script>
    function objHeight( obj ){
        /**
         * Function to adjusting textareas height
         */
        obj.style.height = 'auto';
        obj.style.height = obj.scrollHeight*1.1 + 'px';
    }
</script>

To implement it: objHeight( document.getElementById( 'YOUR_ELEMENT_ID' );

Cgonzalez
  • 23
  • 4