data-grow
Auto-expand textareas as the user types. Uses CSS field-sizing where supported with a JavaScript scrollHeight fallback for older browsers.
Overview
The data-grow attribute makes a textarea automatically expand its height as the user types. It uses the modern CSS field-sizing: content property where supported, falling back to JavaScript scrollHeight measurement for older browsers.
How It Works
Add data-grow to any <textarea>. The init script detects browser support and applies the appropriate strategy:
Modern Browsers (CSS field-sizing)
- Sets
field-sizing: contenton the textarea - If
data-max-rowsis set, appliesmax-block-sizeusing thelhunit (line height) - When content exceeds
max-block-size, the textarea stops growing and scrolls
Fallback (JavaScript scrollHeight)
- Sets
resize: noneandoverflow: hiddenon the textarea - On each
inputevent, resets height toautothen sets it toscrollHeight - If
data-max-rowsis set, calculates max height from line height and caps growth - Switches to
overflow-y: autowhen content exceeds the max height
In both cases, data-grow-init is set to prevent double-binding.
Attributes
| Attribute | Type | Description |
|---|---|---|
data-grow |
boolean | Enables auto-grow behavior on a textarea. |
data-max-rows |
number | Maximum number of rows the textarea can grow to. After this, the textarea scrolls. |
rows |
number | Standard HTML attribute. Sets the minimum number of visible rows. The textarea never shrinks below this. |
data-grow-init |
boolean | Set automatically to prevent double-binding. Do not set manually. |
Basic Auto-Grow
Without data-max-rows, the textarea grows indefinitely to fit its content. The rows attribute sets the initial minimum height.
Max Rows
Set data-max-rows to cap the textarea height. Once it reaches this height, the textarea stops growing and the content scrolls instead.
Min and Max Rows
Combine rows (minimum) and data-max-rows (maximum) to define a growth range. The textarea starts at the minimum and grows up to the maximum.
Combined with data-count
Use data-grow alongside data-count for a textarea that grows while showing a live character or word count. Both attributes work independently on the same element.
In a Form
Auto-grow textareas work seamlessly in forms. The textarea submits its value normally regardless of its visual height.
Shrinking Behavior
The textarea shrinks back down when content is removed. It never shrinks below the initial rows height:
- CSS field-sizing — the browser handles shrinking automatically based on content
- JS fallback — on each input event, the height resets to
autobefore measuringscrollHeight, allowing the textarea to shrink
Events
No custom events are dispatched. The textarea fires standard input and change events. You can observe height changes by reading scrollHeight or style.height on the textarea.
Styling
All styles are gated on [data-grow-init]. Without JavaScript, the textarea renders at its normal rows height with the default resize handle.
The modern CSS path uses field-sizing: content and lh units for clean, declarative sizing. The fallback path uses JavaScript-driven inline styles.
Dynamic Elements
Textareas added to the DOM after page load are automatically enhanced via a MutationObserver. No manual initialization is needed.
Accessibility
- Content remains fully accessible — the textarea grows to show all text, reducing the need for scrolling
- No manual resize is needed — the textarea adapts to content automatically, improving usability for all users
- The native
<textarea>element is preserved, maintaining full screen reader and keyboard support rowssets a visible minimum, ensuring the textarea is never unexpectedly small- When
data-max-rowscaps growth,overflow-y: autoenables scrolling with standard scroll accessibility - Without JavaScript, the textarea renders at its
rowsheight with the native resize handle (progressive enhancement)