Подтвердить что ты не робот

CSS Textarea, который расширяется при вводе текста

У меня есть Textarea, где пользователи могут вводить текст. По умолчанию он имеет высоту 17 пикселей. Однако, если пользователи вставляют большой объем текста, я хочу, чтобы текстовая область расширялась соответствующим образом. Есть ли способ сделать это с помощью CSS? Спасибо заранее!

4b9b3361

Ответ 1

Это невозможно сделать только с помощью CSS. попробуйте плагин jQuery для автозагрузки. https://github.com/jaz303/jquery-grab-bag/blob/master/javascripts/jquery.autogrow-textarea.js

Вы также можете увидеть демонстрацию автошоу здесь http://onehackoranother.com/projects/jquery/jquery-grab-bag/autogrow-textarea.html

Легкий и простой в использовании. Вот как это делается. Определите свой идентификатор textarea. Добавьте файл jquery js до </body>. Затем между тегами script введите команду jquery $("#txtInput").autoGrow();

<body>
    <textarea id="txtInput"></textarea>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script> 

<script>
    $("#txtInput").autogrow();
</script>
</body>

Ответ 2

Этот плагин jQuery действительно отличный: http://www.jacklmoore.com/autosize

Я тестировал кучу этих, и это, безусловно, самое приятное. Также дается пример использования эффекта перехода CSS, который является довольно гладким.

Ответ 3

** Обратите внимание, что это очень похоже на ответ Вуди выше, но хотелось бы немного его расширить и предоставить пример работающего кода теперь, когда Stack позволяет нам их встраивать.

Прочитав все это и попробовав пару плагинов, я обнаружил, что ничего из этого не сработало, как я надеялся. Я сделал следующее - во время прокрутки, прежде чем развернуться, есть небольшое дрожание в верхней части поля, но оно работает для меня. Я использовал jquery, но это можно сделать с помощью javascript так же просто, используя значения отступов вместо использования внутренней высоты:

  • Установить минимальную высоту текстовой области в CSS
  • Установите переполнение скрытым для вертикальной прокрутки (я просто хотел расширить по вертикали)
  • Установите высоту равной высоте прокрутки за вычетом отступов для каждого события keyup, если высота прокрутки была выше, чем высота + отступ (innerHeight).
  • Если высота прокрутки была не выше, я переустанавливаю высоту на 1, а затем устанавливаю высоту на высоту прокрутки за вычетом отступов (чтобы уменьшить высоту). Если вы не сбросите на меньшую высоту изначально, высота прокрутки не будет уменьшаться.

$(function() {
  $('#myTextArea').on('keyup paste', function() {
    var $el = $(this),
        offset = $el.innerHeight() - $el.height();

    if ($el.innerHeight() < this.scrollHeight) {
      // Grow the field if scroll height is smaller
      $el.height(this.scrollHeight - offset);
    } else {
      // Shrink the field and then re-set it to the scroll height in case it needs to shrink
      $el.height(1);
      $el.height(this.scrollHeight - offset);
    }
  });
});
#myTextArea {
  width: 250px;
  min-height: 35px;
  overflow-y: hidden;
}
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<textarea id="myTextArea" placeholder="Hit enter a few times, it should expand"></textarea>

Ответ 4

Для этого вам не нужен плагин. Это работает в текстовых средах любого размера, высоты или размера строки и будет работать только тогда, когда содержимое превышает текстовое поле. Сначала установите переполнение на целевые текстовые области на скрытое и измените размер до нуля, а затем добавьте следующие функции в текстовые поля, которые вы хотите выполнить автозагрузкой. Мало того, что он увеличит размер текстового поля по мере того, как пользователь будет набирать его, он также автоматически сжимает его, когда он удаляет материал.

$('textarea').on('paste input', function () {
    if ($(this).outerHeight() > this.scrollHeight){
        $(this).height(1)
    }
    while ($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))){
        $(this).height($(this).height() + 1)
    }
});

Он работает, измеряя, если высота прокрутки текстового поля больше внешней высоты, что будет только в том случае, если текст будет больше, чем текстовое поле, и он учитывает размер границы для большей точности. Использование вставки и ввода означает, что оно будет увеличиваться только тогда, когда пользователь физически изменит значение текстового поля, а не нажимает любую клавишу. Это мелкое, но текстовое поле не должно расти, когда кто-то нажимает клавишу со стрелкой или что-то в этом роде.

Возможно, было бы разумно добавить параметр No JS, который повторно включает переполнение и изменение размера для тех, у кого нет Javascript, иначе они будут застревать в крошечной коробке.

Ответ 5

Я знаю, что это немного поздно, но я должен сказать, что есть способ использовать <div> с атрибутом contenteditable для имитации желаемого поведения.

.textareaElement {
  width: 300px;
  min-height: 17px;
  border: 1px solid #ccc;
  max-height: 150px;
  overflow-x: hidden;
  overflow-y: auto;
}
<div class="textareaElement" contenteditable></div>

Ответ 6

Используйте JavaScript для этого.

Этот скрипт проверяет длину текстовой области после каждого нажатия клавиши (копирование здесь):

  <textarea name="x" onKeyUp="SetNewSize(this);" cols="5" rows="4"></textarea>
    <script language="javascript">
    function SetNewSize(textarea){
      if (textarea.value.length > 5){
        textarea.cols = 50;
        textarea.rows = 50;
      }  else{
         textarea.cols = 10;
         textarea.rows = 15;
      }
    }
  </script>

Ответ 7

Расширение текстового поля при вводе

Введите что-то в textarea, чтобы увидеть эффект

<script>    
function increseRows(selector)
{
    $(selector).attr("rows", $(selector).val().split("\n").length+1||2);
}
</script>

expanding textarea as you type

Ответ 8

Я использую следующее (с jQuery, конечно):

$(function () {
    'use strict';
    $("textarea").on('change keyup paste input', function () {
        $(this).attr("rows", Math.max($(this).val().split("\n").length || 1, $(this).attr("rows") || 1));
        $(this).css("width", $(this).css("width"));
    }).trigger('change');
});

Обратите внимание, что он реагирует на различные события, только увеличивает количество строк (т.е. не уменьшается), инициирует первоначальное изменение (например, для изменения размера при просмотре в форму с большим количеством строк)

Ответ 9

Это кажется намного более эффективным и обрабатывает max-height

$(ctrl).on('paste input', function () {
    var dyLineHeight, dyMax, dyHeight;        
    if ($(this).outerHeight() > this.scrollHeight)
        $(this).height($(this).outerHeight() - parseFloat($(this).css("borderBottomWidth")) - parseFloat($(this).css("borderTopWidth")));
    dyLineHeight = Math.max(3, parseInt($(this).css("line-height")));
    dyMax = parseInt($(this).css("max-height"));
    while ($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth")))
        {
        dyHeight = $(this).height();
        if (dyHeight >= dyMax)
            break;
        $(this).height(dyHeight + dyLineHeight)
        }
});

Ответ 10

Я искал решение pure js (без jquery в проектах) и в конечном итоге создавал собственное решение. Это очень быстро, без проблем совместимости и не требует дополнительных libs.

Одна деталь, о которой стоит позаботиться, это то, что вам нужно разбить размер перед появлением нового символа, но размер снижается после исчезновения символа (после нажатия на обратное или удаление)

function updateSize(e) {
  let text = e.target.value + String.fromCharCode(event.keyCode);
  e.target.rows = text.split(/\r\n|\r|\n/).length;
}

function keyDownUpdateSize(e) {
  if (event.keyCode != 8 && event.keyCode != 46)
    updateSize(e);
}

function keyUpUpdateSize(e) {
  if (event.keyCode == 8 || event.keyCode == 46)
    updateSize(e);
}

    
  
document.querySelector(selector_to_your_textarea).addEventListener("keydown", keyDownUpdateSize);
document.querySelector(selector_to_your_textarea).addEventListener("keyup", keyUpUpdateSize);

Ответ 11

Старый вопрос, но вы можете сделать что-то вроде этого:

HTML:

<textarea class="text-area" rows="1"></textarea>

JQuery

var baseH; // base scroll height

$('body')
    .one('focus.textarea', '.text-area', function(e) {
        baseH = this.scrollHeight;
    })
    .on('input.textarea', '.text-area', function(e) {
        if(baseH < this.scrollHeight) {
            $(this).height(0).height(this.scrollHeight);
        }
        else {
            $(this).height(0).height(baseH);
        }
    });

Таким образом, автоматическое изменение размера применимо к любому текстовому пространству с классом "текстовая область". Также сокращается при удалении текста.

jsfiddle:

https://jsfiddle.net/rotaercz/46rhcqyn/

Ответ 12

Немного поздно, но это сработало для меня как шарм, это в jquery:

Эта текстовая область имеет предельную высоту 200 пикселей и начальную высоту 22 пикселя. Заполнение очень помогает держать текст в хорошем месте, но мы должны играть с весами в зависимости от размера шрифта.

Есть аналогичный ответ в другом вопросе, но этот является немного более полным.

$('textarea').each(function () {
  // Do something if you want
}).on('input', function () {
  this.style.height = 'auto';
  // Customize if you want
  this.style.height = (this.scrollHeight - 30) + 'px'; //The weight is 30
});
textarea{
    padding: 7px;
    width: 50%;
    height: 22px;
    max-height: 200px;
    resize: none;
    overflow-y: scroll;
    font-size: 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Textarea:</div>
<textarea></textarea>

Ответ 13

Используйте Javascript. textarea ведет себя как текстовое поле, и вы хотите изменить его (вы хотите, чтобы он вел себя как div), поэтому вам нужно взломать поведение, которое вы хотите.

Здесь решение, которое я нашел где-то несколько месяцев назад, но не смог найти его снова. У этого может быть свой собственный вкус, добавленный в:

Разметка:

<div>
  <textarea class='my-textarea' />
  <div className='my-textarea autogrow' style="display: 'none';" />
</div>

Стили:

.my-textarea {
  border: 1px solid #bbb;
  font-family: Helvetica;
  font-size: 15px;
  overflow: hidden;
  padding: 5px;
  resize: none;
}

// Needs same styles as the textarea except overflow.
.autogrow {
  overflow: auto !important;
}

Получить этот прослушиватель событий в событие textarea change:

function growTextarea(e) {
  const { value } = e.target
  const textarea = e.target
  const { grower } = this

  grower.style.display = 'block'
  grower.innerHTML = value.length ? value : 'x'
  textarea.style.height = grower.offsetHeight + 'px'
  grower.style.display = 'none'
}

Как это работает? В основном расширение div - это то, что вы хотите, чтобы расширение textarea вел себя так. Таким образом, вы создаете div со всеми теми же стилями, что и текстовое поле, и добавляете значение textarea в div. Затем вы получите высоту div и установите для нее высоту textarea.

Используя дисплей none и block, div появляется и исчезает, поэтому вы можете измерить его высоту. Вы никогда не увидите его в браузере.

Надеюсь, это сработает для вас!

P.S. Я использую React, поэтому мне пришлось изменить свое решение как агностик рамки. Таким образом, у него могут быть ошибки или синтаксические ошибки. Например. вам может потребоваться запросить документ, чтобы найти diver-производителя.

Ответ 14

Если вы используете Angular2/4, здесь существует отличная директива здесь.

См. список проблем при динамической загрузке данных в текстовое поле для обходного пути. Помимо этой проблемы, он отлично работает с формами ReactiveForms и Template.

Для справки это код директивы:

import { Input, AfterViewInit, ElementRef, HostListener, Directive} from '@angular/core';

@Directive({
    selector: 'textarea[autosize]'
})

export class Autosize implements AfterViewInit {

    private el: HTMLElement;
    private _minHeight: string;
    private _maxHeight: string;
    private _lastHeight: number;
    private _clientWidth: number;

    @Input('minHeight')
    get minHeight() { 
      return this._minHeight;
    }
    set minHeight(val: string) {
      this._minHeight = val;
      this.updateMinHeight();
    }

    @Input('maxHeight')
    get maxHeight() {
      return this._maxHeight; 
    }
    set maxHeight(val: string) {
      this._maxHeight = val;
      this.updateMaxHeight();
    }

 @HostListener('window:resize', ['$event.target'])
    onResize(textArea: HTMLTextAreaElement) {
      //Only apply adjustment if element width had changed.
      if (this.el.clientWidth === this._clientWidth) return;
      this._clientWidth = this.element.nativeElement.clientWidth;
      this.adjust();
    }

 @HostListener('input',['$event.target'])
  onInput(textArea: HTMLTextAreaElement): void {
    this.adjust();  
  }

  constructor(public element: ElementRef){
    this.el = element.nativeElement;
    this._clientWidth = this.el.clientWidth;
  }

  ngAfterViewInit(): void{
    // set element resize allowed manually by user
    const style = window.getComputedStyle(this.el, null);
    if (style.resize === 'both') {
            this.el.style.resize = 'horizontal';
        }
    else if (style.resize === 'vertical') {
            this.el.style.resize = 'none';
    }
    // run first adjust
    this.adjust();
  }

  adjust(): void{
    // perform height adjustments after input changes, if height is different
    if (this.el.style.height == this.element.nativeElement.scrollHeight + "px") return;
    this.el.style.overflowX = 'hidden';
    this.el.style.height = 'auto';
    this.el.style.height = this.el.scrollHeight + "px";
  }

  updateMinHeight(): void{
    // Set textarea min height if input defined
    this.el.style.minHeight = this._minHeight + 'px';
  }

  updateMaxHeight(): void{
    // Set textarea max height if input defined
    this.el.style.maxHeight = this._maxHeight + 'px';
  }

}

Ответ 15

function autoExpand(field) {

    // Reset field height
    field.style.height = 'inherit';

    // Get the computed styles for the element
    var computed = window.getComputedStyle(field);

    // Calculate the height
    var height = parseInt(computed.getPropertyValue('border-top-width'), 10)
                 + parseInt(computed.getPropertyValue('padding-top'), 10)
                 + field.scrollHeight
                 + parseInt(computed.getPropertyValue('padding-bottom'), 10)
                 + parseInt(computed.getPropertyValue('border-bottom-width'), 10);

    field.style.height = height + 'px';

};

Работает для меня

https://gomakethings.com/automatically-expand-a-textarea-as-the-user-types-using-vanilla-javascript/

Ответ 16

var textarea = document.querySelector('textarea');
textarea.addEventListener('keydown', autosize);             
function autosize(){
  var el = this;
  setTimeout(function(){
    el.style.cssText = 'height:auto; padding:0';    
    el.style.cssText = 'height:' + el.scrollHeight + 'px';
  },0);
}
textarea{   
  overflow:hidden; 
  padding:10px;
  width:250px;
  font-size:14px;
  margin:50px auto;
  display:block;
  border-radius:10px;
  border:6px solid #556677;
}
<textarea rows="6" >
CSS Textarea that expands as you type text
rows Specifies the visible number of lines in a text area and cols	Specifies the visible width of a text area
</textarea>

Ответ 17

придумал простое решение для React Angular или Vue.

Вам просто нужно обернуть textarea в div, записать содержимое textarea в div и textarea абсолютную позицию, высоту и ширину textarea в 100% (не забывайте об относительной позиции в div).

Так что теперь div и textarea идеально совмещены, и когда div расширяется из-за текста внутри, textarea автоматически сделает это.

Не забудьте установить одинаковые отступы, размер шрифта и семейство шрифтов.