Automatically Resize Textareas Without JavaScript
The new CSS property field-sizing makes the well known JavaScript tricks for auto-growing textareas obsolete. With field-sizing: content, a form field adapts to its content starting from the very first keystroke, natively in the browser, with no event listener and no layout hacks.
Table of Contents
- 1. The JavaScript Problem with Auto-Resize Textareas
- 2. What Is CSS field-sizing?
- 3. field-sizing: content in Detail
- 4. field-sizing: fixed, the Default Behavior
- 5. Combining min-height and max-height
- 6. Other Supported Form Elements
- 7. Browser Support and the Current Situation
- 8. field-sizing vs. JavaScript Solutions Compared
- 9. Fallback Strategies for Older Browsers
- 10. Summary
- 11. FAQ
1. The JavaScript Problem with Auto-Resize Textareas
Automatically growing a textarea as the user types is one of the most common UX requirements in web forms, and at the same time one of the most persistent problems that native CSS has never been able to solve. The classic approach: an input event listener reads the scroll height of the textarea (element.scrollHeight), sets the height to auto, reads the scroll height again, and then sets the height to that value. This trick works, but it has multiple problems: it requires JavaScript on the initial load, it triggers a double reflow per input event, and it can cause visible flickering during fast typing.
More modern approaches avoid the double reflow using CSS tricks: a hidden element with identical styles and the same content dictates the correct height, or the textarea is wrapped in a grid container whose height is driven by a pseudo-element. All of these solutions are workarounds for a problem that the browser should ideally solve natively. That is exactly what CSS field-sizing does: it delegates the size calculation to the browser, which can access the internal layout mechanism directly, without any JavaScript round trips.
2. What Is CSS field-sizing?
CSS field-sizing is a new CSS property that controls how form elements calculate their intrinsic size. The property has two values: fixed (the previous default behavior, where width, height and size attributes determine the size) and content (the new behavior, where the size adjusts automatically to the content). With field-sizing: content, a textarea behaves like a block element with height: auto, whose height is determined by the text it contains.
The property was implemented by Google Chrome and has been available since Chrome 123 and Edge 123. Firefox has announced support but had not shipped it at the time this article was written. Safari has not announced support either. In practice, this means field-sizing is a progressive enhancement feature: developers can use it today, but they need to implement robust fallbacks for browsers that do not support it.
/* CSS field-sizing: the simplest auto-growing textarea */
textarea {
field-sizing: content;
/* That's it. The textarea now grows with content */
}
/* With sensible constraints */
textarea.comment-field {
field-sizing: content;
min-height: 5rem; /* Minimum height when empty */
max-height: 20rem; /* Maximum before scroll kicks in */
width: 100%;
resize: none; /* Hide manual resize handle when auto-sizing */
overflow-y: auto; /* Scroll within max-height */
}
/* Auto-sizing text input, grows to fit its content */
input[type="text"].auto-width {
field-sizing: content;
min-width: 8rem;
max-width: 100%;
}
/* Select element, sized to match longest option */
select.auto-size {
field-sizing: content;
}
3. field-sizing: content in Detail
With field-sizing: content, the browser removes the fixed sizing that HTML attributes and CSS height/width defaults would otherwise impose on the form element. Instead, the size is calculated like a regular block or inline element: the height of a textarea results from the number of lines the current text occupies, multiplied by the line-height, plus the padding values. When the user types and starts a new line, the element grows immediately, with no JavaScript, no event handler, and no double reflow.
CSS field-sizing: content still respects all standard CSS sizing properties. min-height and max-height work as expected: the element never shrinks below min-height and never grows beyond max-height. Once max-height is reached, the browser automatically switches to scroll behavior if overflow-y: auto is set. Together, these three properties give developers full control over the scaling behavior without writing a single line of JavaScript.
4. field-sizing: fixed, the Default Behavior
The value field-sizing: fixed matches the previous default behavior of all browsers for form elements. With fixed, the size is determined by HTML attributes (rows, cols, size), explicit CSS values (width, height), or browser defaults. The textarea has a fixed height, the user can enlarge it by dragging manually (if resize is not set to none), but the content itself does not change the element's size automatically.
There are situations where fixed is the correct behavior, for instance when a form has a structured layout and a textarea needs to fill a specific area regardless of its content. In such cases it is semantically cleaner to set field-sizing: fixed explicitly rather than relying on the default, so the behavior is documented and intentional. Most modern chat and comment interfaces, on the other hand, benefit from field-sizing: content, since it never forces the user to type into a field that is too small or too large.
/* Auto-growing chat input with constraints */
.chat-input-container {
display: flex;
align-items: flex-end;
gap: 0.5rem;
padding: 1rem;
border-top: 1px solid rgb(226 232 240);
}
.chat-input {
flex: 1;
field-sizing: content;
min-height: 2.5rem; /* Single line height */
max-height: 8rem; /* ~4 lines before scroll */
padding: 0.5rem 0.75rem;
border-radius: 1.25rem;
border: 1px solid rgb(203 213 225);
resize: none;
overflow-y: auto;
line-height: 1.5;
font-family: inherit;
font-size: 0.875rem;
}
.chat-input:focus {
outline: none;
border-color: rgb(124 58 237);
box-shadow: 0 0 0 3px rgb(196 181 253 / 0.5);
}
/* Send button aligns to bottom when textarea grows */
.send-button {
flex-shrink: 0;
align-self: flex-end;
height: 2.5rem;
width: 2.5rem;
border-radius: 50%;
background: rgb(124 58 237);
color: white;
}
5. Combining min-height and max-height
The most effective way to use CSS field-sizing: content combines the property with min-height and max-height. Without min-height, an empty textarea would shrink to the height of a single empty line, often just a few pixels tall, which is hard for users to notice and to interact with. With min-height: 3rem or a similar value, the field always stays at least as tall as a reasonable input area, even when it is empty.
max-height prevents the field from taking up the entire viewport when the text gets very long. Combined with overflow-y: auto, the field scrolls internally once the content exceeds max-height. This is the standard behavior of many chat apps and comment fields: the field grows up to a point, after which older content becomes accessible through scrolling. Without an explicit overflow setting, text beyond max-height would remain visible, causing layout overflow.
/* Full-featured auto-growing textarea with @supports */
@supports (field-sizing: content) {
/* Modern browsers: pure CSS solution */
.auto-textarea {
field-sizing: content;
min-height: 4rem;
max-height: 16rem;
overflow-y: auto;
resize: none;
/* Smooth height transitions */
transition: height 0.1s ease;
}
}
@supports not (field-sizing: content) {
/* Fallback: JS-driven resize via data attribute */
.auto-textarea {
/* Base styles for JS enhancement */
min-height: 4rem;
resize: vertical;
overflow: hidden;
}
/* JS adds data-replicated-value and drives height */
}
/* Input that expands with typed content */
.tag-input {
field-sizing: content;
min-width: 4ch; /* Minimum: 4 characters wide */
max-width: 30ch;
overflow: hidden;
}
6. Other Supported Form Elements
CSS field-sizing does not only work for textareas, it also supports other form elements. On <input type="text"> and other text inputs, field-sizing: content makes the width of the field match the typed text instead of having a fixed width. This is useful for tag input fields, inline editors, and other interfaces where the input field should only ever be as wide as its content.
On <select> elements, field-sizing: content makes the width match the longest available option instead of a browser default width. On number inputs, the width adjusts to the number of digits entered. The behavior is consistent: the element shows its placeholder or its current value and takes up exactly as much space as that content needs, while always respecting min-width/max-width constraints.
7. Browser Support and the Current Situation
At the time of this article (May 2026), Chrome from version 123 and Edge from version 123 fully support CSS field-sizing. Firefox has the property on its roadmap but has not shipped it yet. Safari has not announced support either. This results in a situation where field-sizing works in Chromium browsers, but a fallback is still needed for Safari and Firefox users.
The strategy for production projects is therefore progressive enhancement with @supports: if the browser supports field-sizing: content, the native CSS solution is used. For all other browsers, the proven JavaScript-based resize logic stays active. This is not a step backward, Chrome and Edge users benefit immediately from the cleaner solution, while the experience for Safari and Firefox users stays unchanged.
8. field-sizing vs. JavaScript Solutions Compared
The technical differences between CSS field-sizing and JavaScript-based auto-resize implementations are significant. The CSS solution runs directly inside the browser's rendering process, with no JavaScript round trip and no double layout reflow. JavaScript solutions require at least one reflow per keystroke, often even two when the scrollHeight method is used.
| Criterion | field-sizing: content | JS scrollHeight Trick | CSS Grid Trick |
|---|---|---|---|
| JavaScript required | No | Yes | Yes (minimal) |
| Reflows per keystroke | 0 | 2 | 1 |
| max-height support | Native | Manual | Manual |
| SSR-compatible | Yes | Client only | Yes |
| Browser support 2026 | Chrome/Edge 123+ | All browsers | All browsers |
The CSS grid trick deserves a short explanation: the textarea is embedded inside a grid element, and a hidden div with the same content dictates the correct height. This approach avoids the double reflow of the scrollHeight method, but it still requires JavaScript to keep the content in sync. For projects that need to support all browsers, it remains the preferred fallback method until field-sizing gains wider support.
9. Fallback Strategies for Older Browsers
The recommended fallback strategy uses @supports to separate the native implementation from the JS-based one. The core of the fallback is the grid container trick: the textarea and a hidden pseudo-element, driven by a data-replicated-value attribute, live inside the same grid container. JavaScript keeps the textarea content in sync with the data-replicated-value attribute, which CSS uses to calculate the container's height. The textarea then takes on the container's height automatically via height: 100%.
For Hyva projects using Alpine.js, the fallback is particularly elegant to implement: Alpine's x-model directive keeps the textarea content in sync with a reactive variable that simultaneously populates the hidden element. With @supports (field-sizing: content), the Alpine logic is only loaded when the browser does not support field-sizing natively, which minimizes unnecessary JavaScript in modern browsers.
Mironsoft
Modern CSS forms, UX optimization and performance-focused frontend
Forms that feel like native apps?
We implement modern CSS form patterns, from field-sizing and auto-growing textareas to focused accessibility design and progressively enhanced form experiences with correct fallbacks for every browser.
Form Audit
Analysis of existing form implementations for JS overhead and UX problems
CSS Migration
Replacing JS resize hacks with field-sizing and @supports fallbacks
Alpine.js Integration
Elegant fallback implementation for Hyva projects with a minimal JS footprint
10. Summary
CSS field-sizing: content is the long-awaited native solution for automatically growing textareas and form fields. The property delegates the size calculation to the browser's own layout algorithm, which means zero JavaScript round trips and zero extra reflows. Combined with min-height, max-height and overflow-y: auto, it forms a complete, flexible auto-resize system built entirely in CSS.
The current limitation is browser support: Chrome and Edge have supported field-sizing since version 123, Firefox and Safari not yet. The recommended implementation strategy is progressive enhancement with @supports (field-sizing: content): modern browsers get the CSS solution, older browsers get the proven JavaScript-based fallback. With this strategy, field-sizing can be used in production projects today.
CSS field-sizing: The Essentials at a Glance
Core value
field-sizing: content, the textarea grows automatically with content. No JavaScript, no event listener, no reflow.
Constraints
min-height plus max-height plus overflow-y: auto, full control over minimum and maximum height with internal scrolling.
Browser support
Chrome 123+, Edge 123+. Firefox and Safari in development. Use @supports for progressive enhancement.
Other elements
Also works for input[type=text], select and number inputs, width adapts to content.