Search code examples
javascripthtmltextarea

Issues with textarea's scrollheight increasing inconsistently


This issue is not very easy to explain so I apologize if this question seems confusing.

Basically, I have a <textarea> who's height changes based off its value. If there is any vertical overflow (which would normally produce a vertical scrollbar), I increase the height of the <textarea> to match its scrollHeight property. This seems to work just fine for the first two lines, but when more text is added, I noticed that the point at which the scrollHeight increases is different for each line of text.

Here is a fiddle that demonstrates the strange behavior: http://jsfiddle.net/2zpkf6fL/2/

Type about 5 or 6 lines of text and you will see what I'm talking about.

Can anyone shed some light on this issue? Why does the scrollHeight increase at different points for different lines of text?


Solution

  • Here is how i do what you are looking to do.

    HTML:

        <div class="textarea-container">
      <textarea></textarea>
      <div class="textarea-size"></div>
    </div>
    

    CSS:

    .textarea-container {
      position: relative;
      /* you should change this*/
      width: 50%;
    }
    
    textarea, .textarea-size {
      min-height: 25px;
      /* need to manually set font and font size */
      font-family: sans-serif;
      font-size: 14px;
      box-sizing: border-box;
      padding: 4px;
      border: 1px solid;
    
      overflow: hidden;
      width: 100%;
    }
    
    textarea {
      height: 100%;
      position: absolute;
      resize:none;
    
      /*
      "pre" or "preline" or "normal" fixes Chrome issue where
        whitespace at end of lines does not trigger a line break.
      However, it causes the text to exhibit the behavior seen with
        "pre" that is described below.
       */
      white-space: normal;
    }
    
    .textarea-size {
      visibility: hidden;
    
      /*
      Pre-wrap: preserve spacing and newlines, but wrap text.
      Pre: preserve spacing and newlines but don't wrap text.
    
      "pre" does not wrap well on Firefox, even with word-wrap:break-word.
      "pre" on Chrome works with word-wrap, but exhibits different behavior:
      Instead of entire words being moved to the next line for wrapping,
      the browser will cut words in the middle for wrapping.
      "pre-line" has Firefox issues
      */
      white-space: pre-wrap;
      /* Required for wrapping lines in Webkit,
        but not necessary in Firefox if you have white-space wrapping
        (pre-wrap, normal, pre-line) already set */
      word-wrap: break-word;
      overflow-wrap: break-word;
    }
    

    SCRIPT:

    var textContainer, textareaSize, input;
    var autoSize = function () {
      textareaSize.innerHTML = input.value + '\n';
    };
    
    document.addEventListener('DOMContentLoaded', function() {
      textContainer = document.querySelector('.textarea-container');
      textareaSize = textContainer.querySelector('.textarea-size');
      input = textContainer.querySelector('textarea');
    
      autoSize();
      input.addEventListener('input', autoSize);
    });
    

    Here is jsfiddle