I used to fix this with a JavaScript resize listener. Now field-sizing: content do it in one line.
Here’s another feature that we as web developers have been waiting for for years. It is CSS field-sizing. It landed in Chrome 123, Safari 26.2, and most recently in Firefox 152. Making it available in all major engines. Here’s how it works. By default, text areas have a fixed size, and if the content doesn’t fit, you get a scroll bar. But if you give the text area field-sizing: content; it will size itself to fit its content in both width and height.
Now, this example looks bad, so of course you probably want to set a minimum width or have it span full width, meaning it will only grow vertically. And as you’d expect, you can also provide maximum sizes. So in this case, we get scroll bars once the content exceeds seven lines of text. This replaces a bunch of JavaScript hacks that we were previously using to achieve the same effect. But it’s not just useful on text areas. It also works on text inputs, including the subsets like number inputs and search inputs.
It respects placeholders, as in the field is sized to the full placeholder content if the field is empty. Now for select elements, by default they are the width of the longest option. But with field sizing content, they size just to the selected option.
For select elements that display as a list box, as in they have the multiple attributes or a size attribute greater than one, it sizes to display all the options, which is great news if you’re one of the five developers that actually use these list boxes. But yes, the most common use will be on text areas, meaning we can remove yet another JavaScript dependency from our code bases. If you want to read the full documentation and play with demos, you can find all of that stuff on MDN.
The actual functional demo of this new CSS baseline property:
What Developers Used to Do
So, what did developers do? They resized the text area with JavaScript. First, you reset the height of the text area to auto. This is important because otherwise the text area might grow when new text is added, but it will not shrink when the text is deleted. Then you read the scroll height of the text area. This is the actual vertical space the complete text content needs. And finally, you assign that measurement back to the text area as the new inline height.
textarea.addEventListener("input", () => {
textarea.style.height = "auto";
textarea.style.height = textarea.scrollHeight + "px";
});
So every time the user types or deletes a character, JavaScript measures the content and updates the layout. And I know this is not the most complicated script in the world, but I’m very happy that you can now fix this with one line of CSS.
The One Line of CSS
On the textarea, you add field-sizing: content.
textarea {
field-sizing: content;
}
The default value of field-sizing is fixed. Changing this to content tells the browser to calculate the preferred size from the actual content instead. When I type another line, the field grows automatically. When I delete text, it shrinks again.
Customizing the Size
And of course, you can still customize everything else. You could add a min-height to keep it large enough, and a max-height to limit how tall it can become. Here I would use something like 3lh. lh represents the current line height, so this is pretty useful for text areas.
textarea {
field-sizing: content;
min-height: 3lh;
max-height: 10lh;
}
Now you can also add a max height and set this to something like 10lh. That way the text area can grow and shrink naturally, but it also has a minimum and maximum size.
Watch Out for the Resize Property
Now, one important thing to watch out for is the resize property. Text areas use resize: both by default, which allows the user to drag the corner to resize the text area. The problem is, once we resize this text area, field-sizing will have no effect. When I add more lines of text, the scroll bars will appear again. It will no longer adjust the height dynamically.
So I would probably set resize: none when I want to use field-sizing.
textarea {
field-sizing: content;
min-height: 3lh;
max-height: 10lh;
resize: none;
}
I hope you found this helpful and learned something new.
Did you learn something good today as a developer?
Then show some love.
© Muhammad Usman
WordPress Developer | Website Strategist | SEO Specialist
Don’t forget to subscribe to Developer’s Journey to show your support.



Top comments (0)