<textarea> elements don’t change size based on the content they contain. In fact, there isn’t any simple HTML or CSS way to make them do that. Kinda funny, as that seems like a reasonable use-case. But of course, there are ways, my friend. There are always ways.
I was thinking about this after Remy Sharp blogged about it recently in the context of inline
Non-input elements expand naturally
It’s weird to me that there is no way to force an input element to mimic this behavior, but alas.
We can make any element editable and input-like with the
<span class="input" role="textbox" contenteditable> 99 </span>
<span> will naturally grow to be the width it needs to be for the content it contains. If it was a
<div> or any other element that is block-level, it would also expand vertically as needed.
But are non-input elements accessible?
I’m not entirely sure. Notice I put
role="textbox" on the element. That’s just a best-guess based on some docs.
Even if that’s helpful…
- What about the fact that forms can be submitted with the Enter key?
- What about the idea that form data is often serialized and sent along, while the code that’s doing it probably isn’t looking for a span?
- Does it actually read the same as an input in a screen reader?
- What other things¹ do inputs naturally do that I’m not thinking of?
As attracted as I am to the idea that we can get auto-resizing for free from the browser by using non-input elements, I’m also a little worried about (my) unknown usability and accessibility risk.
Resizing actual input elements
So let’s say we stick with
<textarea>. Can we make them resize-able even though it’s not particularly natural?
For textareas, one classic technique is to count the number of line-breaks, use that to set the height, then multiply it by the line-height. That works great for preformatted text, like code, but not at all for long-form paragraph-like content.
Here are all these ideas combined.
data-* attribute on the element equal to the value of the input. The input is set within a CSS grid, where that grid is a pseudo-element that uses that
data-* attribute as its content. That content is what stretches the grid to the appropriate size based on the input value.
I absolutely know that you fellow web nerds have solved this six ways to Sunday. Let’s see ’em in the comments.
- Eric Bailey hit me up with a few thoughts off the top of his head: (1) There’s no accessible name. (2) It probably won’t work with voice control. (3) It will get ignored in High Contrast Mode.