← Read

Design · · 5 min read

Auto-growing textareas, without the JavaScript: field-sizing is Baseline

One CSS declaration replaces the scrollHeight listener every form has copied for a decade. What field-sizing affects, and the HTML attributes it quietly switches off.

A <textarea> that grows as you type used to need JavaScript: listen for input, reset the height to auto, read scrollHeight, set the height back. Every design system has a copy of it, and every copy has the same bug on paste.

The CSS replacement is one declaration:

textarea {
  field-sizing: content;
}

field-sizing became Baseline newly available on 16 June 2026, when Firefox 152 shipped it. Chromium has had it since March 2024 and Safari since 26.2, so the wait was on Firefox.

It also does more than the textarea trick, and it turns off some HTML attributes you may be relying on. Both are worth knowing before you add it globally.

What the property does

CSS Form Control Styling Level 1 defines two values:

ValueBehaviour
fixedThe control takes the default preferred size the host language gives it. This is the initial value.
contentThe control sizes itself to its content, ignoring that default preferred size.

The spec calls these "elements with default preferred size" — elements whose intrinsic size is fixed regardless of their content. A <textarea> is the obvious one: by default it's four rows tall whether it holds nothing or an essay.

The property is not inherited, so field-sizing: content on a wrapper won't reach the inputs inside it. Set it on the controls.

Which controls it affects

Wider than most write-ups suggest. Per MDN's reference:

ControlWhat content does
<input> of type text, search, url, tel, email, password, numberShrinks to fit the typed text; grows as you type
<input type="file">Shrinks to fit the displayed filename, and resizes when a new file is chosen
<textarea>Grows in width first; once width is constrained, grows in height; scrolls once height is constrained too
<select> (drop-down)Width follows the currently selected option rather than the longest one
<select multiple> or with sizeTall enough to show every option without scrolling

The <select> behaviour is the one that surprises people. By default a drop-down is sized to its longest option, so the control never moves when the selection changes. With field-sizing: content it resizes on every change, which shifts the layout around it. That's rarely what you want in a form row, and it's the main reason to apply this property per control rather than to input, select, textarea wholesale.

Set bounds, not a size

A text input with field-sizing: content and no minimum width collapses to the width of the text caret when it's empty. A <textarea> with a lot of pasted text grows until something stops it.

Both problems have the same fix: constrain with min- and max-, never with width or height.

.comment {
  field-sizing: content;
  min-width: 20ch;
  max-width: 60ch;
  min-height: 3lh;  /* three lines, whatever the line height is */
  max-height: 12lh;
}

Setting width or height outright re-imposes a fixed size and cancels most of the benefit — the control can still reflow within that box, but it can no longer size itself. min-width/max-width let it grow and shrink between limits, which is what a resilient form field actually needs.

A placeholder changes the empty state too: a control with a placeholder is rendered wide enough to show the placeholder text, so that's often the minimum width you wanted anyway.

The attributes it switches off

This is the migration trap. With field-sizing: content set:

  • rows and cols on <textarea> stop having an effect. They set the default preferred size, and content ignores it. A form that relied on rows="8" for its visual rhythm will collapse to a single line when empty.
  • size on <input> stops having an effect, for the same reason.
  • size on <select> almost stops having an effect. The browser still reads it to decide whether to render a drop-down (size="1") or a list box, but a list box then shows all its options regardless of the number you set.

Two attributes still do something useful:

  • maxlength caps growth: the control stops getting wider once the character limit is reached.
  • placeholder, as above, establishes a sensible empty width.

If you're adding field-sizing to an existing form, search for rows=, cols= and size= first. Those are the elements that will change shape.

What it doesn't do

  • It doesn't animate. The spec gives field-sizing a discrete animation type, and the resize itself is a layout change, not a transition. The height jump as a new line appears is instant. There's no CSS-only way to ease it.
  • It doesn't scroll for you. Once a max-height is reached the control scrolls internally, the same as any overflowing box.
  • It doesn't help non-form elements. field-sizing applies to controls with a default preferred size. A contenteditable div already sizes to its content and needs nothing.

Rolling it out safely

The graceful path is to treat it as an enhancement over the layout you already have, because an unsupported browser drops the declaration and keeps the rows-based size:

textarea {
  min-height: 5lh;
}

@supports (field-sizing: content) {
  textarea {
    field-sizing: content;
    min-height: 3lh;
    max-height: 15lh;
  }
}

Keep rows on the element as the pre-support fallback, and set the supported minimum inside the @supports block. Then delete the JavaScript autosize helper — including the resize observer, the paste handler and the hidden mirror element it probably uses.

Browser support

At the time of writing, from browser-compat-data:

BrowserVersion
Chrome and Edge123
Chrome for Android123
Firefox (desktop and Android)152
Safari (macOS and iOS)26.2

FAQ

Does field-sizing work on <select>?

Yes, and it changes behaviour more than you might want: a drop-down resizes to the selected option instead of the longest one. Apply it deliberately, not in a blanket rule.

Why did my textarea collapse to one line?

field-sizing: content ignores the rows attribute. Set a min-height in CSS — min-height: 3lh gives you three lines regardless of the line height.

Can I animate the height change?

No. The resize is a layout change with a discrete animation type, so it happens in one frame.

Is it inherited?

No. Set it on each control, or on a selector that matches them.

Sources

More to read