DEV Community

wlto
wlto

Posted on

create an auto-expanding textarea with just javascript

in this tutorial, i'll show you how to create a textarea component that satisfies these requirements:

  1. auto-expands as the user types (ie. growing in height).
  2. is accessible.
  3. works with “textwithnowhitespaceinbetweenlikethisone”.
  4. works with any font.

the solution i'm proposing does not require any extra javascript library. keep in mind the constraints above as we go through this together.

the idea

the idea is that we would like to calculate the final height of the textarea as the user types in each keystroke. here is an illustration:

Screenshot 1

to do this, it's crucial to know how many lines there are in the current text when compared to the textarea's height, which includes its padding, top and bottom border width (if any).

let's first establish the html and css code for this textarea.

Screenshot 2

there's a few things to pay attention to here:

essential values

as noted in the code comment, some css values are going to be used in javascript so that we can calculate the final height of the textarea. these values are:

  1. line height
  2. top and bottom paddings
  3. top and/or bottom border width

Screenshot 3

in this example, for simplicity, i will just be duplicating those values in javascript by creating constants that have the same values. of course, you can also just get those values in javascript as well if you'd prefer, using something like window.getComputedStyle.

box-sizing

for this to work, we need to set box-sizing to border-box.

rows attribute

notice that i've set the rows attribute of the textarea to 1. this resets the default number of rows that is applied to textarea.

the juicy part

now let's go into the juicy part - javascript.

let's first duplicate those essential CSS values inside our script tag.

Screenshot 4

then, let's query the textarea element and add an event listener to it. this will allow us to detect the input event as the user types into the textarea.

Screenshot 5

then, if we run the code on our web browser, we will start seeing some logs as we type into the text box.

Screenshot 6

we don't want our textarea to be resizable, since by the end of this tutorial, we would have an auto-resize textarea. so let's set its resize css attribute to none in javascript.

Screenshot 7

the reason why we want to do it in javascript and not css is because we want to allow users who disable javascript to be able to use our textarea field like usual.

final steps

now, the question is, how do we calculate the final height of a textarea element that doesn't have pre-determined content?

we need a few pieces of information:

  1. what is the actual height of the content that is entered, excluding all the paddings and borders?
  2. how many lines of content have been entered?

as you might know, whenever we enter text into a textarea element, if the content ends up overflowing the element's pre-set height, it will and should be scrollable. this allows the user to see the overflowing content. we need to use this scrollable height value to determine the height of the content that is being entered.

luckily, the browser has something built in that can help us with that. and it is Element.scrollHeight.

Screenshot 8

with this information, we can calculate the actual height of the content. dividing that value by the textarea's line height, and we will get the number of lines.

Screenshot 9

and it is working as expected.

Screenshot 10

finally, we can calculate the final height of the textarea using this formula below:

extra_vertical_spacing = top_padding + bottom_padding + top_border_width + bottom_border_width
final_height = (number_of_lines x line_height) + extra_vertical_spacing
Enter fullscreen mode Exit fullscreen mode

however, in my example, i only have top padding, bottom padding and bottom border width. hence, my code becomes this:

Screenshot 11

and we can set the calculated height value back to textarea.

Screenshot 12

at this point, this is our result.

Screenshot 13

it seems to work fine. but what happens if we delete our text and the number of lines reduces?

Screenshot 14

you'll see that there is a bug here. it seems like our textarea is not automatically re-adjusting its height after we delete our text.

when we delete our text, scrollHeight does not change. as detailed in mozilla's documentation, it's used to determine the minimum height required to fit all the content within the textarea withour scrollbar. hence, it will not decrease since it is assuming that the previous content we entered is the minimum amount of content.

we can fix this behaviour by setting the height property of the textarea to auto on each keystroke. this ensures that the height is reset before the calculated final height is applied to the text box.

Screenshot 15

with that change, our final textarea works like a charm

Screenshot 16


thank you for reading!
wlto

Top comments (0)