field-sizing: content: Auto-Sizing Form Fields Natively
A hidden clone element measuring content on every keystroke causes real layout thrashing on large forms. This property lets the browser's own layout engine handle the resizing instead.
Paul Radford — Full-Stack Developer & Editor. Paul is a full-stack developer and editor of template.tips. Articles here are AI-drafted and reviewed by Paul, who knows the code well enough to catch what's wrong and cut the hype.

The field-sizing: content CSS property tells a text input, textarea, or select to grow and shrink based on its actual content, without JavaScript, resize observers, or hidden mirror elements. Set it on the element and the browser recalculates intrinsic width or height as the user types, respecting min-width, max-width, and similar constraints you define.
What problem does this actually solve?
Before this property existed, auto-growing a textarea meant one of two approaches: a JavaScript library that measures a hidden clone of the content and syncs height on every keystroke, or a contenteditable div dressed up to look like a textarea. Both work, but both carry cost. The mirrored-element trick causes layout thrashing on large forms, breaks on paste events if you forget to debounce, and needs constant upkeep whenever font metrics change. The contenteditable route sacrifices native form semantics: autofill quirks, spellcheck differences, and accessibility tree oddities that show up inconsistently across screen readers.
field-sizing removes the JavaScript layer entirely for the common case. The browser's own layout engine, which already knows the exact glyph widths and line-wrapping rules for the rendered font, does the measurement. That is inherently more accurate than a JS-based mirror, which has to painstakingly replicate every CSS property (padding, letter-spacing, font-feature-settings) that affects text metrics, and inevitably drifts out of sync when someone edits the stylesheet six months later.
Basic syntax and default values
The property accepts two keywords: fixed (the historical default, sizing controlled entirely by CSS width/height and rows/cols attributes) and content (intrinsic sizing based on the field's value).
1/* Textarea that grows vertically as the user types,2 capped so it never exceeds 12 lines' worth of height */3textarea.auto-grow {4 field-sizing: content;5 min-height: 3lh; /* roughly 3 lines, using the lh unit */6 max-height: 12lh;7 overflow-y: auto; /* scroll once max-height is hit */8}910/* Single-line input that widens with input,11 useful for tag editors or inline rename fields */12input.inline-edit {13 field-sizing: content;14 min-width: 4ch;15 max-width: 40ch;16}Note the lh and ch units doing real work here. lh resolves to the computed line height of the element, so max-height: 12lh reliably caps a textarea at twelve lines regardless of font size. ch approximates the width of the "0" character in the current font, which is a reasonable proxy for average character width in monospace-ish or numeric contexts, though it is less predictable with proportional fonts containing wide glyphs.
Does it work with select elements?
Yes, and this is arguably the more novel use case, since native selects have historically been sized either by their widest option (in some browsers) or by a fixed width you set manually, with no consistent cross-browser behavior. With field-sizing: content, a <select> sizes to whichever option is currently chosen, not the widest possible option. That means the box visibly resizes when the user picks a different value.
1<!-- Select that hugs the selected option's width -->2<select class="tight-select">3 <option>Short</option>4 <option>A considerably longer option label</option>5 <option>Mid</option>6</select>1.tight-select {2 field-sizing: content;3 max-width: 300px; /* prevent runaway width on the long option */4}This behavior is genuinely useful for compact UI (toolbar dropdowns, inline settings) where you do not want a short "Yes/No" select occupying the same width as a much longer sibling. It can also be surprising to users if the layout around the select is not designed to tolerate width changes on every selection, so test it inside flex or grid containers where a shifting width might reflow neighboring elements unexpectedly.
What breaks if I reach for this on every input?
Not every input benefits from content-based sizing, and using it indiscriminately creates its own usability problems.
Password fields are a poor fit. A shrinking or growing password input leaks information about length through layout alone, which is a minor but real side-channel, especially on shared screens or during screen recording for support tickets. Keep password inputs at a fixed width.
Search boxes and command palettes usually want a stable width too, because a search bar that visibly grows as you type shifts every element to its right, which reads as jittery rather than responsive. Reserve field-sizing: content for cases where a changing size is itself useful information to the user, such as a textarea that clearly shows "you are writing a lot" through its growing height, or a tag input where width naturally maps to content length.
There is also a subtler layout gotcha: content-sized fields inside CSS Grid or Flexbox can fight with min-width: auto defaults. Grid and flex items have an implicit minimum size based on their content by default, and combining that with field-sizing: content can produce fields that refuse to shrink below their content width even when you want them to wrap or truncate. If you see a form field blowing out a flex row, add min-width: 0 on the flex item wrapping the field, or overflow: hidden on the field itself, before assuming the property is broken.
How do I handle browsers that do not support it yet?
As of early 2026, field-sizing is supported in Chromium-based browsers (Chrome and Edge shipped support starting with Chrome 123, released in March 2024) and in other Chromium derivatives that track upstream closely. Firefox and Safari had not shipped support as of late 2025, according to the MDN browser compatibility table for field-sizing, so treat this as a progressive enhancement, not a baseline feature, until you confirm current support on caniuse.com.
The property degrades gracefully by design. Unsupported browsers simply ignore the declaration and fall back to whatever fixed sizing behavior the element already had (its rows, cols, width, or height). That makes it safe to ship without a JavaScript fallback in most cases, as long as your fixed-size defaults are still reasonable on their own. Do not build a feature where the fixed fallback is unusable (for example, a 2-row textarea meant to hold paragraphs of text on non-supporting browsers); pick fallback dimensions generous enough to work without the auto-grow behavior.
1/* Defensive pattern: reasonable fixed size first,2 auto-sizing layered on top for browsers that support it */3textarea.comment-box {4 width: 100%;5 min-height: 6lh; /* usable default even without field-sizing support */6 field-sizing: content;7 max-height: 20lh;8}You can also gate more advanced behavior behind a feature query if you need JS awareness of support:
1// Detect support before wiring up any JS-based enhancement2// that assumes native auto-sizing is active3const supportsFieldSizing = CSS.supports("field-sizing", "content");45if (!supportsFieldSizing) {6 // Fall back to a manual auto-grow script only when needed,7 // instead of running redundant measurement logic everywhere.8 import("./textarea-autogrow-fallback.js");9}This pattern keeps the JS fallback out of the critical path for browsers that already handle sizing natively, which matters for performance on forms with many fields, since the fallback script typically attaches input listeners and forces layout reads on every keystroke.
Testing it properly before you ship
Manual testing catches most of what matters here, and it takes less time than writing automated coverage for a purely visual CSS property. Open the field in a real Chromium browser, type a mix of short and very long content, paste in a multi-paragraph block, and check three things: does the field respect min- and max- bounds, does resizing cause any visible layout jump in sibling elements, and does the field size correctly with content set programmatically (via .value = in JS) rather than only through typed input, since some early implementations handled these two paths inconsistently before the spec stabilized in the CSS Sizing Level 4 draft.
Then switch to a non-supporting browser (Safari is the easiest check as of this writing) and confirm the fallback dimensions are still usable on their own, not just present. A min-height that technically exists but renders a two-line textarea for a comments field is a fallback in name only. If your form is public-facing and you cannot control which browser a user arrives in, budget time for this second pass every time, because it is the step teams skip under deadline pressure and the one that produces support tickets later.
Related Articles

Styling Form States: Beyond :valid and :invalid
A required email field showing an error state before anyone's typed a single character isn't a bug, it's a spec quirk. Here's the pseudo-class combination that fixes the timing problem.

The :focus-visible Pseudo-Class: Better Focus States Without the Pain
outline: none with nothing to replace it made entire products unusable for keyboard and switch-device users for years. Here's the pseudo-class that finally fixed that false choice.

appearance: none: Styling Native Controls Without a Reset Framework
A checkbox renders completely differently on macOS Safari versus Windows Chrome by default. appearance: none lets you target just the controls that need surgery, not a global reset.