自動リサイズテキストエリア
入力量に合わせて高さが自動で伸びるテキストエリア。scrollHeight に合わせて高さを更新し、文字数カウンタも連動する。
プレビュー
入力
操作実際に入力して試せます。
仕様書
- 向く場面
- チャット・メッセージなど行数が読めない入力
- 空欄は1行、書くほど伸ばしたい欄
- 上限までは伸ばし超えたらスクロールにしたい入力
- 避ける場面
- 固定の高さで枠を揃えたい一覧フォーム
- 数千字の長文(max-height 以降は普通のスクロール)
- 構成要素
- ラベル
- テキストエリア
- 文字数カウンタ
- 持っている状態
- 通常
- フォーカス
- キーボード
Tab で欄へ移動。入力で高さが伸び、max-height 180px 以降はスクロールに切り替わる
- 支援技術
label[for] と aria-describedby でカウンタを結ぶ。カウンタ自体は live にせず、残り 60/20 字の段階を跨いだときだけ visually-hidden の aria-live=polite で通知(毎打鍵の読み上げを避ける)。色は補助
- 動き
枠色・リング・カウンタ色 180ms。高さの変化は即時(transition 無し)
デザインの要点
- 高さは一度 auto に戻してから scrollHeight を読む。戻さないと文字を削っても縮まない
- max-height 180px で止めてスクロールに切り替える。無限に伸びると送信ボタンが画面外へ逃げる
- 高さの変化に transition を付けない。1行ごとに滑ると打鍵の手応えが遅れて見える
- カウンタは「N / 300」の分数表記。残り数だけだと上限が分からず、書く量の見当がつかない
実装メモ
高さは一度 height:auto に戻してから scrollHeight を代入して測り直すのがコツ(文字を削ったときに縮まなくなるのを防ぐ)。max-height で上限を設け、それ以上はスクロールに切り替えています。
コード(コピーして使えます)
<form class="ag-form" novalidate>
<label class="ag-label" for="ag-area">メッセージ</label>
<textarea
id="ag-area"
class="ag-area"
rows="1"
maxlength="300"
placeholder="入力すると高さが自動で伸びます"
aria-describedby="ag-count"
></textarea>
<div class="ag-footer">
<span class="ag-count" id="ag-count">0 / 300</span>
</div>
<span class="ag-sr" id="ag-live" aria-live="polite"></span>
</form>