EdgeCases Logo
Feb 2026
CSS
Surface
6 min read

CSS field-sizing: Auto-Growing Inputs Without JavaScript

Auto-growing textareas and inputs without JavaScript—finally native in CSS. One property replaces ResizeObserver hacks.

css
field-sizing
forms
textarea
input
auto-grow

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/cols attributes 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: content makes inputs/textareas auto-grow natively
  • Always set min-width or use placeholder to prevent collapse
  • Use max-width/max-height to 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

Related Insights

Explore related edge cases and patterns

CSS
Surface
CSS sibling-index() and sibling-count(): Dynamic Sibling Styling
6 min
CSS
Surface
CSS contain: Render Isolation for Performance
6 min

Advertisement