CSS Field-Sizing Table
| Piece | What it does | Field note |
|---|---|---|
field-sizing: content | Size to the content | Inputs/textareas/selects grow to FIT - the fixed-cols era ends |
textarea without rows | Grows as typed | The autogrow textarea with zero JavaScript |
select fit-content | Wide as longest option | No more truncated option lists or oversized selects |
max-width guard | The stop growing | content + max-width: 100% - grow but never blow the layout |
vs size attribute | HTML hint vs CSS law | size=30 is static; field-sizing recomputes with the content |
input vs textarea | Both apply | Single-line inputs shrink to placeholder/content too |
Empty state = placeholder size | The sizing floor | Empty input sizes to placeholder text - keep placeholders short |
Form layout stability | The trade | Growing fields reflow neighbors - grids and labels absorb it |
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
- 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.
- Fit selects to options: select { field-sizing: content; } - the control is as wide as its longest option, no truncation, no oversized default.
- 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.