Back to notes

CSS field-sizing: inputs that grow as you type

25 October 2026·
cssformsbaselineux
Live demoOpen full screen

A textarea that grows as you type used to need a script that measured scrollHeight on every keystroke. Now it takes one line of CSS: field-sizing: content. With Firefox 152 shipping it on June 16, 2026, the property is Baseline, so it works in Chrome, Edge, Firefox and Safari.

Type in the demo above, or press "Type it for me": the blanks in the sentence widen with every letter, the dropdown shrinks to the option you picked, and the chat box gains a line at a time until it hits its limit. Flip the switch to fixed and you get the old behaviour back on the same markup.

What it is and why it matters

Form controls have always had a size that ignores what's inside them. An <input> is just as wide whether it holds "Al" or a full street address, a <textarea> is however many rows and cols it gets, and a <select> is as wide as its longest option. The spec calls these "elements with default preferred size".

field-sizing takes two values:

  • fixed: the default. The control keeps that default preferred size.
  • content: the browser works out the control's size from its content and ignores the default.

That's the whole API. What makes it worth knowing is how many small annoyances it removes: chat composers, comment boxes, inline "fill in the blank" forms, tag inputs, compact filters with a <select> that shouldn't reserve space for its longest option. All of that used to mean JavaScript that measured text, ran on every input event and fought with fonts that hadn't loaded yet.

How it works

This is the CSS behind the demo, trimmed to the parts that matter:

/* The technique: fields take the size of their content */
input, textarea, select {
  field-sizing: content;
}

/* Inline blanks: never narrower than 3 characters,
   never wider than their container */
.sentence input,
.sentence select {
  min-width: 3ch;
  max-width: 100%;
}

/* Chat: fixed width, the height grows up to a limit and then scrolls */
.composer textarea {
  width: 100%;
  min-height: 2.75em;
  max-height: 7.5em;
  resize: none;
}

Three behaviours are going on there:

  1. Text inputs shrink-wrap their text. The text, email, search, tel, url, number and password types grow and shrink with the value. If there's a placeholder, the field is wide enough to show it.
  2. A textarea grows sideways first, then down. With nothing stopping it, a textarea with field-sizing: content behaves like a single-line field. Once it can't get any wider, because it has a fixed width or hits a max-width, it starts adding lines. When it reaches max-height, a scrollbar shows up. That's why the chat in the demo has width: 100%: the width stays put and only the height changes. The spec uses exactly this case as its example.
  3. A dropdown fits the selected option. A regular <select> changes width as you pick different options. A list box (multiple, or size above 1) shows every option instead of scrolling.

In the demo the only JavaScript that touches sizes is the ResizeObserver that prints the pixel readouts, plus the fallback I'll get to below. The growing itself is all CSS.

The gotchas

I checked each of these in Chromium with a small test page before writing them down. They match what MDN describes:

  • Always set a min-width. An empty input with field-sizing: content and no minimum is as wide as the text cursor. In my test it measured 9 pixels. That's why the demo uses min-width: 3ch.
  • size, rows and cols stop doing anything. They set the default preferred size, and content ignores that. An <input size="40"> with field-sizing: content was exactly as narrow as one without the attribute.
  • A fixed width and height cancel the effect. If you set both, the control has a fixed size again. Use min-* and max-* to keep it within bounds, or fix only the width, as in the chat.
  • maxlength also caps the size, because the field stops growing when no more characters fit.
  • Mind the container. In a CSS grid, an item's automatic minimum size can let a growing field push the whole card wider than the screen. That's exactly what my first version of this demo did at 375 px. grid-template-columns: minmax(0, 1fr) on the parent fixes it, and so does min-width: 0 on the item.

Browser support

According to MDN's compatibility data, Chrome and Edge 123 (March 2024) were first, followed by Safari 26.2 (December 2025) and Firefox 152 (June 2026). That makes it Baseline newly available from June 16, 2026. For the next few months, some people will still be on browsers without it.

The good news is that the fallback is free: a browser that doesn't understand field-sizing ignores the declaration and draws the form exactly as it always has. If the old size is acceptable, you don't need anything else. If it isn't, check for support and only load the old trick when the property is missing:

if (!CSS.supports('field-sizing', 'content')) {
  // Old trick: measure and set the size by hand
  textarea.addEventListener('input', () => {
    textarea.style.height = 'auto';
    textarea.style.height = textarea.scrollHeight + 'px';
  });
}

The demo does exactly that, and shows a notice when it's running on the fallback. In CSS you can use @supports (field-sizing: content) for the same check.

What to keep an eye on

  • The spec home has changed. field-sizing now lives in CSS Form Control Styling Level 1 (it moved there from CSS UI 4). That draft also covers appearance: base and fully styleable form controls, so expect more news in this area.
  • Long fields in real layouts. A field that grows changes the layout around it. In flex and grid that's fine, but a max-width is always worth having.
  • Removing old code. If you have a dependency or a hook whose only job is to auto-size textareas, it's a good candidate to delete once your audience is on browsers from the last few months.

Sources