CSS Field-Sizing Table

PieceWhat it doesField note
field-sizing: contentSize to the contentInputs/textareas/selects grow to FIT - the fixed-cols era ends
textarea without rowsGrows as typedThe autogrow textarea with zero JavaScript
select fit-contentWide as longest optionNo more truncated option lists or oversized selects
max-width guardThe stop growingcontent + max-width: 100% - grow but never blow the layout
vs size attributeHTML hint vs CSS lawsize=30 is static; field-sizing recomputes with the content
input vs textareaBoth applySingle-line inputs shrink to placeholder/content too
Empty state = placeholder sizeThe sizing floorEmpty input sizes to placeholder text - keep placeholders short
Form layout stabilityThe tradeGrowing fields reflow neighbors - grids and labels absorb it
Reference: the MDN field-sizing reference. field-sizing: content ends the fixed-form-control era: inputs, textareas and selects size themselves to their CONTENT - the autogrow textarea (the classic JavaScript plugin) becomes one CSS line, selects stop truncating their longest option, and empty inputs size to their placeholder. The guard that ships with it: max-width: 100% so growth never blows out the layout, and empty-state sizing means placeholder text doubles as the minimum-width hint. Bottom line: Chrome-first (gate with @supports), growing fields reflow neighbors - the trade is form-layout stability for content-fit honesty. Related tools: form elements table (the fields being resized), input types table (the types that benefit), and interpolate-size table (the sibling 2024 sizing feature).

field-sizing: content ends the fixed-form-control era: inputs, textareas and selects size themselves to their CONTENT - the autogrow textarea (decades of JavaScript plugins measuring scrollHeight on every keystroke) becomes one CSS line.

Bottom line: the guard that ships with it is max-width: 100% - content-sizing will happily grow a textarea wider than the page, so the growth needs a ceiling. And the empty state sizes to the PLACEHOLDER text, which quietly becomes your minimum-width hint: keep placeholders short or fields shrink oddly.

The honest part: growing fields reflow their neighbors - every keystroke can move the button below. That is the trade field-sizing makes: form-layout stability for content-fit honesty. Stable forms keep fixed widths; conversational and dynamic forms get content sizing.

How to use

  1. Kill the autogrow plugin: textarea { field-sizing: content; min-height: 3lh; max-width: 100%; } - grows as typed, floored at three lines, capped at the container.
  2. Fit selects to options: select { field-sizing: content; } - the control is as wide as its longest option, no truncation, no oversized default.
  3. Gate and guard: @supports (field-sizing: content) around the declarations - non-supporting browsers keep your rows/cols and size attributes.

Frequently asked questions

Why was the autogrow textarea a JavaScript problem for so long?

Because HTML sized it statically. A textarea's size came from rows/cols attributes (or CSS width/height) - fixed boxes the content may overflow into scrolling. The autogrow pattern (grow as the user types) needed JS: listen to input, measure scrollHeight, set an explicit height, repeat every keystroke and on every font-load - each measurement a layout read. field-sizing: content inverts ownership: the browser sizes the field to its content natively, recomputing during its own layout pass. The plugin's remaining value after this: minimum heights (min-height in CSS covers it), max caps (max-width/max-height), and animation between states - all CSS-expressible.

What does field-sizing do to a select element?

Fixes the standing width problem. A select traditionally sizes to its WIDEST option (or the size attribute), so a dropdown with one long entry forces a huge control on a short form, or truncates options with ellipsis. field-sizing: content sizes the CLOSED control to its currently-selected option - compact when 'Weekly' is selected, wider when the user picks the long option, with the dropdown list itself still full-width. The layout consequence: the control's width changes as the selection changes, so form columns need to absorb that - another instance of the feature's core trade, content honesty for layout stability.

Why does the empty state size to the placeholder, and how do I use that?

Content-sizing needs a content signal, and an empty input's only content is its placeholder text - so the field shrinks to fit the placeholder (or collapses to a minimum). This makes placeholder text a SIZING CONTRACT: placeholder='Search' gives a compact search box; a long placeholder gives a wide empty field. The deliberate pattern: short placeholders plus min-width (or min-height for textareas) as the explicit floor - size by intent rather than accident. The trap to document: teams used to long instructional placeholders will see wide empty fields and blame the feature; instructions belong in labels, not placeholders anyway.

What is the honest adoption state and the stability trade?

Chrome-first, gated. field-sizing shipped in Chrome (2024) - Firefox and Safari still use rows/cols and size attributes, so @supports (field-sizing: content) wraps the declarations and non-supporting browsers keep the static sizes that always worked. The deeper trade is layout stability: a content-sized field changes width on every keystroke, reflowing neighboring elements - acceptable in conversational UIs, search bars and inline editors; hostile to rigid grid forms where a growing field pushes the submit button around. The design decision is per-form: fixed fields for structured data entry, content-sized fields where the form is a conversation.

Related tools