Добрый день.

Озадачился сегодня вопросом автоматического растягивания textarea в зависимости от текста.
Поискав, понял, что самый изящный вариант — вариант с дублирующим скрытым div-ом. Но меня поразило насколько он неизящен.

В результате переработки найденного кода (а точнее написания с нуля), получил более изящное решение:

function textAreaHeight(textarea) {
        if (!textarea._tester) {
            var ta = textarea.cloneNode();
            ta.style.position = 'absolute';
            ta.style.zIndex = -2000000;
            ta.style.visibility = 'hidden';
            ta.style.height = '1px';
	        ta.id = '';
	        ta.name = '';
            textarea.parentNode.appendChild(ta);
            textarea._tester = ta;
            textarea._offset = ta.clientHeight - 1;
        }
	    if (textarea._timer) clearTimeout(textarea._timer);
        textarea._timer = setTimeout(function () {
            textarea._tester.style.width = textarea.clientWidth + 'px';
            textarea._tester.value = textarea.value;
            textarea.style.height = (textarea._tester.scrollHeight - textarea._offset) + 'px';
            textarea._timer = false;
        }, 1);
    }


Для использования необходимо лишь «повесить» обработчик textAreaHeight на событие onkeydown:
<textarea rows="1" cols="120" onkeydown="textAreaHeight(this)"></textarea>

Вы можете «повесить» обработчик любым другим удобным для вас способом. Не забудьте, что при программном изменении текста необходимо вызвать эту же функцию.

Никаких CSS, никакого дополнительного HTML-кода.