Vue.js 3 — Auto-Resize Textarea

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!


Mentioned Resources

Explore the Library

Find interesting tutorials and solutions for your problems.