web-dev-qa-db-ja.com

テキストを入力すると展開するCSS Textarea

ユーザーがテキストを入力できるTextareaがあります。デフォルトでは、高さは17ピクセルです。ただし、ユーザーが大量のテキストを挿入する場合、それに応じてテキスト領域を拡大します。 CSSでこれを行う方法はありますか?前もって感謝します!!

38
Spencer

これはCSSだけでは行えません。 autogrow 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

軽量で使いやすいです。方法は次のとおりです。テキストエリアIDを定義します。 _</body>_の前にjquery jsファイルを含めます。次に、スクリプトタグ間で、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>
_
24
Hussein

このjQueryプラグインは本当に素晴らしいプラグインです。 http://www.jacklmoore.com/autosize

私はこれらの束をテストしましたが、これは群を抜いて素晴らしいです。また、非常に滑らかなCSSトランジション効果の使用例を示します。

20
sirkitree

**これは上記のWoodyの回答と非常に似ていますが、少し拡張して、Stackで埋め込みできるようになった実行中のコード例を提供したかったことに注意してください。

これをすべて読んで、いくつかのプラグインを試したところ、期待したとおりに機能しないことがわかりました。私は次のことをしました-フィールドが拡大する前にスクロールするとフィールドの上部にわずかなジッターがありますが、私にとってはうまくいきます。私はjqueryを使用しましたが、内側の高さを使用する代わりにパディング値を取得することにより、javascriptで簡単に実行できます。

  • CSSのtextareaに最小の高さを設定します
  • 垂直スクロールのオーバーフローを非表示に設定します(垂直に拡大したかっただけです)
  • スクロールの高さが高さ+パディング(innerHeight)よりも高かった場合、各keyupイベントのパディングを除いたスクロール高さに高さを設定します。
  • スクロールの高さがそれよりも高くなかった場合、高さを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>
16

私はこれが少し遅れていることを知っていますが、<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>

適切なオーバーフロー値を使用して最小高さと最大高さを設定するだけで、完全に機能する純粋なCSS拡張テキストボックスがあり、これも十分にサポートされています。

enter image description here

14
momciloo

これにはプラグインは必要ありません。これは、任意のサイズ、高さ、行サイズのテキストエリアで機能し、コンテンツがテキストエリアを超える場合にのみ機能します。最初に、対象のテキストエリアのオーバーフローを非表示に設定し、サイズをなしに変更してから、自動拡張するテキストエリアに次の機能を追加します。ユーザーが入力するたびにテキストエリアのサイズが大きくなるだけでなく、アイテムを削除するときに自動的に縮小されます。

$('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)
    }
});

Textareaのスクロールの高さが外側の高さよりも大きいかどうかを測定することで機能します。これは、textareaが保持できるテキストよりも多くのテキストがある場合のみになります。貼り付けと入力を使用すると、ユーザーがキーを押したときとは対照的に、ユーザーがテキスト領域の値を物理的に変更したときにのみ増加します。それはささいなことですが、誰かが矢印キーか何かを押しても、テキストエリアは成長しません。

Javascriptを持っていない人のためにオーバーフローとサイズ変更を再度有効にするNo JSオプションを追加するのが賢明かもしれません。そうしないと、小さなボックスで立ち往生します。

13
Woody Payne

これにはJavaScriptを使用します。

このスクリプトは、そこにあるすべてのキーストロークの後にテキスト領域の長さをチェックします( here からのコピーパスタ):

  <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>
4
Nikita Barsukov

これははるかに効率的であるようで、最大高さを処理します

$(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)
        }
});
1
Glenn Kreisel

少し遅れましたが、これは魅力のように私のために働いた、それは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>
1
N0XT

入力中にテキストエリアを拡大

テキストエリアに何かを入力して、効果を確認します

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

expanding textarea as you type

1

私は純粋なjsソリューション(プロジェクトにjqueryがない)と最終的に独自のソリューションを作成することを探していました。非常に高速で、互換性の問題はなく、追加のライブラリは必要ありません。

注意が必要なことの1つは、新しい文字が表示される前にボックスのサイズを変更する必要があるが、文字が消えた後に(バックスペースを押すか削除してから)ボックスのサイズを小さくすることです

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);
1
Marek Kirejczyk

古い質問ですが、次のようなことができます:

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);
        }
    });

このように、自動サイズ変更は、クラス「text-area」を持つすべてのテキストエリアに適用されます。また、テキストが削除されると縮小します。

jsfiddle:

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

1
rotaercz

私は以下を使用します(もちろん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');
});

さまざまなイベントに応答し、行数を増やすだけで(つまり、減少しません)、初期変更をトリガーします(たとえば、多くの行があるフォームに戻るときにサイズを変更する)

1
DigitalDan
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>
0
rajmobiapp
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/

0
Mauro Salgado

JavaScriptを使用します。 textareaは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の展開をどのように動作させるかです。したがって、textareaと同じスタイルのdivを作成し、textareaの値をdivに入れています。次に、divの高さを取得し、textareaの高さをそれに設定します。

Display noneとblockを使用すると、divが表示および非表示になり、高さを測定できます。ブラウザで実際に表示されることはありません。

これがあなたのために働くことを願っています!

追伸Reactを使用しているため、フレームワークに依存しないようにソリューションを変更する必要がありました。バグや構文エラーが発生する可能性があります。

0
A.Williams

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';
  }

}
0
rmcsharry