DEV Community

Cover image for Delete Your Auto-Resize Textarea JS. CSS Does It Now.
Parsa Jiravand
Parsa Jiravand

Posted on Originally published at bestpractic.org

Delete Your Auto-Resize Textarea JS. CSS Does It Now.

Open any comment box you've built in the last five years and there's a decent chance this is sitting in a useEffect or an input listener:

textarea.style.height = "auto";
textarea.style.height = `${textarea.scrollHeight}px`;
Enter fullscreen mode Exit fullscreen mode

Two lines. Copy-pasted from a Stack Overflow answer, a gist, or your own last project. It's the unofficial industry-standard way to make a <textarea> grow as someone types, because <textarea> has never — not once, in thirty years of HTML — known how to size itself to its own content. Until now it does, and most people haven't heard.

Why the two-liner is worse than it looks

Here's the fuller version most people actually ship, because the two-liner alone doesn't hold up:

function autoGrow(el) {
  el.style.height = "auto";
  el.style.height = `${el.scrollHeight}px`;
}

textarea.addEventListener("input", () => autoGrow(textarea));
window.addEventListener("resize", () => autoGrow(textarea)); // width changes reflow the text
autoGrow(textarea); // run once for pre-filled content
Enter fullscreen mode Exit fullscreen mode

Reset the height to auto, read scrollHeight, write it back. Do that on every keystroke. It works, but notice what "works" is quietly costing you:

  • Two forced reflows per keystroke. Setting height: auto invalidates layout; reading scrollHeight forces the browser to recompute it synchronously before it'll give you the number. On a slow device, in a form with several of these, that's measurable jank while someone's just trying to type.
  • A visible flicker. Reset-then-remeasure means the box visibly shrinks for one frame before snapping back, especially noticeable on a fast paste of several paragraphs.
  • You have to remember the resize listener. Miss it, and resizing the browser window leaves stale heights until the next keystroke — a bug that never shows up in your testing because you never resize your own window mid-demo.
  • It still doesn't handle a <input type="text"> growing with its content, which is the same underlying problem in a different tag. You'd write a second version of this hack.

None of this is a bug in your code. It's the ceiling of what's possible when the browser gives you no way to say "size to content" and JavaScript has to fake it by measuring pixels after the fact.

The one-line fix

textarea {
  field-sizing: content;
}
Enter fullscreen mode Exit fullscreen mode

That's the whole thing. No listener, no scrollHeight, no reflow-and-flicker dance. field-sizing is a CSS property that changes how form controls compute their intrinsic size: instead of the browser guessing a fixed box from rows/cols (or a fixed width for <input>), content tells it to size the box to fit what's actually typed, and grow or shrink live as the user edits.

It isn't limited to <textarea>. Point it at a text <input> and the field widens as someone types, the same trick people currently fake with a hidden <span> measuring text width behind the scenes:

input[type="text"].auto-width {
  field-sizing: content;
}
Enter fullscreen mode Exit fullscreen mode

As of mid-2026 this is Baseline "Newly available" — it started in Chromium browsers in 2024 and has since landed in the current stable release of every core engine, Firefox and Safari included. "Newly available" is the first rung on Baseline's ladder, though, not the last: it means the latest stable version of each browser understands it, not that every visitor is already on that version. If you need to support someone on an older browser, that's exactly what a plain, unstyled textarea already does — it just won't auto-grow, and nothing breaks. Ship it behind nothing and it degrades to the old fixed-size box on its own.

The gotcha nobody mentions in the one-liner

Here's the part that bites people who copy just the CSS and stop reading: field-sizing: content on its own means the box has no upper bound. Let someone paste in a full paragraph, or ten, and your neat little comment box grows into a page-length column, pushing your submit button somewhere past the fold.

You still need a ceiling — you just set it in CSS instead of computing it in JS:

textarea {
  field-sizing: content;
  max-height: 12lh; /* stop growing after ~12 lines */
  overflow-y: auto; /* scroll inside the box past that */
}
Enter fullscreen mode Exit fullscreen mode

max-height caps the growth, overflow-y: auto lets the box scroll internally once it hits that cap instead of just clipping the text. 12lh — twelve line-heights — is a nice unit to reach for here because it scales with the font size instead of hardcoding a pixel guess.

Try both settings live below: type a short reply, then paste in a wall of text, and watch where the ceiling kicks in. Then flip the toggle to see the exact JS hack this replaces, side by side.

🎮 Try it yourself

▶️ Open the interactive playground →

Runs right in your browser — poke at it and watch the concept react live.

One property, one caveat

field-sizing: content replaces a hack that's been copy-pasted into countless codebases since <textarea> shipped without an opinion on its own size. It removes a resize listener, two forced reflows per keystroke, and a visible flicker on paste — for the cost of one CSS declaration and remembering to pair it with max-height.

If you're still shipping the scrollHeight version because "it works," it does — but so did jQuery .animate() before transition existed. Go check whether the browsers you actually support have caught up, and see how much JS you get to delete.

What's the oldest DOM-measuring hack you're still maintaining that you suspect CSS has quietly solved by now? Drop it below — I'll tell you if there's already a property for it.

🧠 Test yourself

Think it clicked? Take the 7-question quiz →

Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.


🚀 Want more like this? Every guide, playground, and quiz lives on bestpractic.org — open it and sign up free so the next one finds you.

Thanks for reading! Let's stay connected:

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.