in this tutorial, i'll show you how to create a textarea component that satisfies these requirements:
- auto-expands as the user types (ie. growing in height).
- is accessible.
- works with “textwithnowhitespaceinbetweenlikethisone”.
- 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:
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
.
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:
- line height
- top and bottom paddings
- top and/or bottom border width
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.
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.
then, if we run the code on our web browser, we will start seeing some logs as we type into the text box.
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.
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:
- what is the actual height of the content that is entered, excluding all the paddings and borders?
- 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
.
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.
and it is working as expected.
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
however, in my example, i only have top padding, bottom padding and bottom border width. hence, my code becomes this:
and we can set the calculated height value back to textarea
.
at this point, this is our result.
it seems to work fine. but what happens if we delete our text and the number of lines reduces?
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.
with that change, our final textarea
works like a charm
thank you for reading!
wlto
Top comments (0)