Basic Input
A labelled text input with helper text wired to it via aria-describedby.
6 個のフレームワーク初級
A textarea that grows to fit its content, with no scrollbar and no drag handle.
<!--
A textarea cannot measure itself while it has a height. The two-line dance in
resize() is the whole technique and the order is not negotiable:
1. height = 'auto' - collapse it so scrollHeight reports the CONTENT
2. height = scrollHeight - grow the box to exactly that
Skip step 1 and scrollHeight just reports the current height back at you, and
the box never shrinks when text is deleted.
-->
<div class="grow-field">
<label class="grow-field__label" for="grow-field-note">Message</label>
<textarea
class="grow-field__input"
id="grow-field-note"
name="note"
rows="1"
placeholder="Write a message…"
aria-describedby="grow-field-note-help"
></textarea>
<p class="grow-field__help" id="grow-field-note-help">The box grows as you type.</p>
</div>
<script>
document.querySelectorAll('.grow-field__input').forEach(function (el) {
function resize() {
el.style.height = 'auto';
el.style.height = el.scrollHeight + 'px';
}
el.addEventListener('input', resize);
// Run once on load - the field may be server-rendered with a value already
// in it, and a pre-filled box that starts at one row defeats the point.
resize();
});
</script>| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
label必須 | string | - | 読み込み中に読み上げられるアクセシブルなラベル。 |
value必須 | string | - | 指標の現在値。フォーマット済みの文字列を渡します。 |
disabled | boolean | false | 操作を無効にし、コントロールを淡色表示にします。 |
className | string | - | ルート要素にマージされる追加クラス。 |
A textarea cannot measure itself while it has a height, so the two-line dance is the whole technique and the order is not negotiable: set `height = "auto"` to collapse the box, then `height = scrollHeight` to grow it to the content. Skip the collapse and `scrollHeight` reports the current height back at you - the box grows but never shrinks. `resize-none` because the box sizes itself and a handle would fight the script; `overflow-y-hidden` because the height always equals the content, so a scrollbar could only ever be a phantom stealing horizontal space. The React variants use `useLayoutEffect`, not `useEffect`: the resize must land before paint or the box visibly snaps on every keystroke.