CSS field-sizing: Auto-Growing Inputs Without JavaScript
Auto-growing textareas and inputs without JavaScript—finally native in CSS. One property replaces ResizeObserver hacks.
Auto-growing textareas have required JavaScript since forever. The hack: a hidden
<div> mirroring the content, measuring its height, applying it back.
Or ResizeObserver. Or a library. CSS field-sizing: content finally kills
all of that—one property, and inputs/textareas shrinkwrap their content natively.
The Basic Fix
Apply field-sizing: content and the element sizes to its contents:
textarea {
field-sizing: content;
}
/* That's it. The textarea now grows with its content. */
This works on <textarea>, text <input> types
(text, email, password, search, tel, url, number), and even <select>
elements. The browser handles all the resize logic.
What It Actually Does
field-sizing accepts two values:
- fixed (default) — Traditional behavior. Size determined by
size/rows/colsattributes or CSS - content — Size adjusts to fit contents, respecting min/max constraints
When set to content, the element ignores size, rows,
and cols HTML attributes. It becomes a pure shrinkwrap container.
The Gotchas
Empty Inputs Collapse
Without content, an input with field-sizing: content shrinks to just the
cursor width—often invisible:
/* ❌ Problem: Empty input nearly invisible */
input {
field-sizing: content;
}
/* ✅ Fix: Set a min-width */
input {
field-sizing: content;
min-width: 10ch; /* At least 10 characters wide */
}
/* ✅ Better: Use placeholder for initial sizing */
<input type="text" placeholder="Enter your name">
The placeholder attribute is your friend here—the element sizes to fit
the placeholder text when empty, providing natural minimum sizing.
Unbounded Growth Breaks Layouts
Without constraints, the element grows until it overflows its container:
/* ❌ Problem: Textarea grows forever horizontally */
textarea {
field-sizing: content;
}
/* ✅ Fix: Constrain maximum size */
textarea {
field-sizing: content;
min-width: 200px;
max-width: 100%;
min-height: 2.5em;
max-height: 300px;
}
For textareas, once max-width is reached, content wraps and the element
grows vertically. Once max-height is hit, scrolling kicks in.
Select Elements Behave Differently
<select> elements have unique behavior with field-sizing: content:
/* Drop-down: width changes with selected option */
select {
field-sizing: content;
}
/* If user selects "California" vs "NY", width changes */
/* Multi-select: shows ALL options, no scrolling */
select[multiple] {
field-sizing: content;
}
/* All options visible at once—could be huge! */
For multi-selects, this is often not what you want. The listbox
expands to show every option regardless of the size attribute.
Fixed width/height Override It
If you set explicit width or height, field-sizing: content
is effectively disabled for that dimension:
/* ❌ width: 300px cancels horizontal auto-sizing */
textarea {
field-sizing: content;
width: 300px; /* Fixed, not auto-sized */
}
/* ✅ Use min/max constraints instead */
textarea {
field-sizing: content;
min-width: 200px;
max-width: 500px;
}Replacing the JavaScript Pattern
Here's the classic auto-resize hack that's now obsolete:
/* BEFORE: The JavaScript hack */
function autoResize(textarea) {
textarea.style.height = 'auto';
textarea.style.height = textarea.scrollHeight + 'px';
}
textarea.addEventListener('input', () => autoResize(textarea));
// Plus: ResizeObserver for container changes
// Plus: MutationObserver if content changes programmatically
// Plus: handling the initial size on page load
/* AFTER: Pure CSS */
textarea {
field-sizing: content;
min-height: 2.5em;
max-height: 50vh;
}No JavaScript, no event listeners, no forced reflows, no scroll height calculations. The browser handles everything in the layout engine.
Production Pattern
A robust auto-growing textarea for production:
textarea.auto-grow {
field-sizing: content;
/* Readable minimum */
min-width: min(100%, 300px);
min-height: 3lh; /* 3 line-heights */
/* Prevent layout explosions */
max-width: 100%;
max-height: 50vh;
/* Padding doesn't break sizing */
padding: 0.75rem 1rem;
/* Resize handle still works */
resize: vertical;
}
/* With a placeholder for empty state */
<textarea
class="auto-grow"
placeholder="Write your thoughts..."
></textarea>
The resize: vertical property still works—users can manually resize
beyond the auto-determined size if they want to.
Browser Support
field-sizing shipped in 2024-2025:
- Chrome/Edge: 123+
- Safari: 18+
- Firefox: 132+
For older browsers, the property is simply ignored—you get the default fixed sizing.
Progressive enhancement works perfectly here: add field-sizing: content
and your existing JavaScript fallback continues to work in unsupported browsers.
Key Takeaways
field-sizing: contentmakes inputs/textareas auto-grow natively- Always set
min-widthor useplaceholderto prevent collapse - Use
max-width/max-heightto prevent layout explosions - Avoid fixed
width/height—they override auto-sizing - Selects behave uniquely; multi-selects show all options
- JavaScript auto-resize hacks are now obsolete
Advertisement
Explore these curated resources to deepen your understanding
Official Documentation
Tools & Utilities
Related Insights
Explore related edge cases and patterns
Advertisement