It would be best if you had a way for users to share their thoughts when building a content-centric website. Users may comment on tutorials, videos, or other types of content. A common way of sharing comments is the HTML textarea that provides a multiline input field.
Using textareas can be tricky related to the user experience: if the default size of the textarea is too large, it’s taking up lots of space on your site. If the textarea is too small, it’s cumbersome for users to share larger texts because they need to scroll … and scrolling in a small area is icky, too. A textarea that auto-resizes depending on the content is a way to keep both advantages.
This tutorial shows you how to autosize an HTML textarea with Vue.js.
Vue.js 3 Series Overview
Autosize a Textarea with Vue.js
This tutorial uses the useTextareaAutosize
Vue.js composable from VueUse to resize a textarea when the text would become scrollable. The useTextareaAutosize
composable provides the variables needed to resize the visible textarea and retrieve its content. Use the returned textarea
and input
references and assign them to the HTML markup to connect the user element with the composable.
Here’s a code sample on how to use the useTextareaAutosize
composable.
<script setup lang="ts">
import { useTextareaAutosize } from '@vueuse/core'
const { input, textarea } = useTextareaAutosize()
</script>
<template>
<textarea
ref="textarea"
v-model="input"
placeholder="Put your message here"
/>
</template>
The returned variables from calling the useTextareaAutosize()
composable work fine. We find their naming not ideal in most situations and suggest refining their names to match your context. For example, you may be working in a user profile that allows users to type a message. A better name than input
for the v-model text is userMessage
.
<script setup lang="ts">
import { useTextareaAutosize } from '@vueuse/core'
const {
input: userMessage,
textarea: userMessageTextarea,
} = useTextareaAutosize()
</script>
<template>
<textarea
ref="userMessageTextarea"
v-model="userMessage"
placeholder="Put your message here"
/>
</template>
That’s all you need to set up to make the textarea resize when text becomes multiline.
Putting the Textarea Resize Together Manually
You can also compose the functionality yourself with the help of the useTextareaAutosize
composable. You’re then using the triggerResize
function to size the textarea on a given action, like when the user removes the selection from it.
Here’s the sample code on how you could use a reference to an HTML element in combination with the useTextareaAutosize
composable:
<script setup lang="ts">
import { useTextareaAutosize } from '@vueuse/core'
const textareaUserMessage = ref()
const userMessage = ref('Hello Marcus')
const { triggerResize } = useTextareaAutosize({ element: textareaUserMessage })
</script>
<template>
<textarea
ref="textareaUserMessage"
v-model="userMessage"
placeholder="Put your user message here"
@blur="triggerResize"
/>
</template>
Enjoy!