You asked an AI for a chat box. It gave you a textarea that grows as you type. Then you deleted a few lines and the box stayed tall, like a coat that won't come off a hook.
Now you've read somewhere that CSS can do this alone, and you're looking at an input listener — code that runs every time you type — in your editor wondering: can I delete it, or is it holding something up? Let's open the hood.
The code you were handed
Here is the typical recipe, next to the CSS that claims to replace it. Both are on one screen on purpose.
<!-- OLD: JavaScript does the sizing -->
<textarea id="msg" rows="2"></textarea>
<script>
const box = document.getElementById('msg');
box.addEventListener('input', () => {
box.style.height = 'auto'; // reset first, so it can shrink
box.style.height = box.scrollHeight + 'px'; // then measure and grow
});
</script>
<!-- NEW: the browser does the sizing -->
<style>
textarea {
min-height: 3lh; /* never smaller than three lines */
max-height: 10lh; /* never taller than ten, then it scrolls */
}
@supports (field-sizing: content) {
textarea { field-sizing: content; }
}
</style>
Notice the first line inside the listener: 'auto'. That line is the reason your box didn't shrink when you deleted text, and I'll prove it in a moment. The second thing to notice is that the CSS version keeps a plain textarea with a minimum and maximum height as its fallback. The sizing property only switches on where the browser understands it.
Why the box won't shrink
I ran the listener in a real browser (Chromium 141, driven by Playwright 1.56.1), typed eight lines, then pressed Backspace one key at a time while logging the box height. Remove the 'auto' reset and the trace looks like this:
176 176 176 176 176 176 176 174 172 170 168 166 164 162 160 ...
The box holds at 176 pixels while there is still text filling it, then loses a sliver per keystroke, never keeping pace with the text. After deleting everything it was still 78px tall, where it started at 58.
Why? The browser's scrollHeight reports how tall the content is, but never less than the box's own current height. I checked: with the height forced to 300px and one character inside, scrollHeight read 298. After setting the height to 'auto' it read 56. So the reset isn't superstition. It is the step that lets the box measure its text instead of measuring itself. With the reset in, the same test returned to 60px, the minimum, after the text was deleted.
A second person reran the whole recipe on a different machine and got the same shape. The 298 matched to the pixel, and so did the leak: a flat hold, then exactly 2px lost per keystroke. Her absolute heights were different from mine (her box topped out at 124px, not 176), because the pixel counts depend on your font and padding. So do not hunt for my numbers on your screen. Look for the behaviour: a box that holds, then trickles down, versus a box that snaps back.
I did not chase why the leak is exactly 2px a keystroke. It's reproducible, so I'm reporting it, not explaining it.
What the listener was for, and who took over
Put plainly, that listener has one job: make the box as tall as its text. field-sizing: content is the browser taking the same job. I ran both in the same page in Chromium 141. The property was supported (CSS.supports returned true, and it returned true for the lh unit too), and after eight lines and a full delete:
after 8 lines after deleting all listener 176px 60px field-sizing 178px 60px plain fallback 60px 60px
Same behaviour, 2px apart at the tall end. The second run saw the same 2px gap (124 against 126) on its own fonts. Past thirty extra lines, both the listener box and the CSS box stopped at 200px, which is the max-height guardrail doing its work. The plain textarea never grew at all.
So in Chromium, yes: the browser took over the job. Chromium is one browser, though. I did not run Firefox or Safari, and I won't tell you what they do. What I can give you, next, is what MDN's compatibility data lists for it.
Proving the fallback isn't load-bearing
Here is the part people skip. I took the same textarea and forced the property off after the page loaded, setting field-sizing back to fixed. Then I typed eight lines. The box stayed at 60px, with 176px of content scrolling inside it.
That is what a visitor on an older browser sees: a three-line box that scrolls. It isn't broken. It's less pretty. It's also a useful picture of what deleting the JavaScript risks. Those visitors lose the auto-growing, nothing else.
Newly available is not Widely available
Before the rule, one line of vocabulary. Baseline is a label that tells you how widely a web feature works across the major browsers. Newly available means it has just started working in all of them, and Widely available means it has been that way long enough, roughly two and a half years, that you can stop thinking about it.
Now the support figures, which were checked against MDN's browser-compat-data, the dataset the support tables are built from. For field-sizing it lists Chrome 123, Edge 123, Safari 26.2 and Firefox 152. The feature is on the standards track and is not marked experimental. Firefox was the last engine to ship it, which is why the label is still the young one. I would expect the Newly available date to sit around June 2026, but that date is the one thing I could not confirm, because the compat data does not carry it. Look it up yourself on the feature's Baseline page rather than taking my month.
Those version numbers are still a snapshot. They tell you the latest browsers have it. They tell you nothing about the phone your visitor bought in 2023 and never updated.
So Newly available means: it works in the latest of everything, and your visitor is not guaranteed to be on the latest of anything.
The delete-or-keep rule
Here's the rule I'd give a friend. Three steps, in order.
Step 1: Keep the JavaScript today, but stop depending on it. Add the field-sizing block with its @supports wrapper, and give the textarea a min-height and max-height. Now you have two systems doing one job. Where field-sizing works, the browser sizes the box. Where it doesn't, the old listener still does. Widely available sits roughly two and a half years after Newly, so for a feature this fresh you'll be running both for a while — that's shipped ugly, not a failure.
Step 2: Check the label for your audience. Look up field-sizing on MDN or caniuse and compare it with the browsers your visitors actually use. If you have no analytics, assume strangers on older phones.
Step 3: Delete the listener only when the label reads Widely available, or when your own support list already clears it. Then remove the whole script block, including the 'auto' line, and keep the CSS.
One more caution, for the stretch when both are on the same box. I put them together and checked: the listener wins, because it writes an explicit height onto the element on every keystroke, and an explicit height overrides field-sizing. In my run the box took the listener's height and only switched to field-sizing once I cleared that inline height — they landed 2px apart, not fighting. So keeping both is safe; the property just waits in reserve until you delete the script.
Why this matters
When code comes from an AI, you inherit decisions you never made. That listener exists because it was the usual recipe for the job. Browsers keep absorbing jobs like this. Each time, the question isn't "is the new thing cool?" It's "what was the old code for, and is that job now somebody else's?" Answering it protects you from two opposite failures: keeping dead code forever, or deleting code that a visitor's older browser was quietly relying on.
The failure mode this rule prevents is the second one: you delete the script, a visitor on an older Safari gets a two-line box, and you decide the JavaScript was load-bearing without ever finding out it was only the fallback's job.
Your next step
Open the page where your AI-written textarea lives and first check the listener has that 'auto' reset line — if your box won't shrink, that one missing line is the whole fix, and it's a ten-minute win. Then add the CSS block above, with min-height and max-height, and keep the listener for now. Type ten lines, delete them, and watch the box return to its minimum. Finally, open the support table for field-sizing, write down which browsers it lists, and put the date next to it. That note is your delete rule.