Skip to main content
Vuetify0 v1.0 is here
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

BuTextarea

Edit this page
Report a Bug
Open issues
Copy Markdown

Renders elementIntermediateAug 24, 2026

Bulma’s .textarea as a native multiline control — the same Input family as BuInput, grown to paragraph-length values, with fixed in place of rounded and plaintext.

Note

Reference: Textarea on bulma.io↗︎ — classes and visual variants. This page is the JavaScript.

Usage

v-model is a string and defaults to ''. rows is a native attribute, not a prop — it falls through to the textarea and sets how many lines are visible before scrolling. The box still resizes unless you pass fixed.

A wrapper is optional. Put it in a BuField when you need a label; put it in a BuControl when you need a loading spinner.

<script setup lang="ts">
  import { BuControl, BuField, BuLabel, BuTextarea } from '@paper/bulma'

  import { shallowRef } from 'vue'

  const message = shallowRef('')
</script>

<template>
  <BuField>
    <BuLabel>Message</BuLabel>

    <BuControl>
      <BuTextarea v-model="message" placeholder="e.g. Hello world" />
    </BuControl>
  </BuField>
</template>

Anatomy

vue
<script setup lang="ts">
  import { BuTextarea } from '@paper/bulma'
</script>

<template>
  <BuTextarea />
</template>

Composed on v0

BuTextarea is a renderless Input.Root around Input.Control rendered as a native <textarea>. The compound is element-agnostic — the whole wiring surface (value sync, focus tracking, the validation pipeline, the aria attributes) applies to a textarea exactly as it does to an input. v0 supplies the behavior; the skin picks the element with as="textarea" and the .textarea class.

There is no rounded and no plaintext. Those are input modifiers. The extra knob here is fixed, which emits has-fixed-size and disables the resize handle.

Inside an existing Input.Root the wrapper is skipped and the control binds to the ambient context instead. The ambient-root contract is the same as BuInput: the root owns v-model, disabled, readonly, required, name, form, id, label and every validation prop; only color, size and fixed still apply on the textarea.

The markup you know

The Bulma tab is the markup published on bulma.io↗︎, captured verbatim in the conformance fixture. The Vue tab is the component that renders it. The conformance suite diffs the two on every test run — element for element, class for class.

html
<textarea class="textarea" placeholder="e.g. Hello world"></textarea>

Loading is not a textarea modifier. is-loading goes on the wrapping BuControl, and size on that control pairs the spinner with the textarea size.

Examples

Fixed size

fixed adds has-fixed-size and that is the whole resize story. The handle disappears; the box stays at the height rows (or the UA default) set. Reach for it when a resize handle would shove neighbouring controls around — a comment box in a tight card, a notes field in a horizontal form.

Leave it off when the reader might have more to say than the visible rows. The default textarea resizes vertically, which is the signal that an essay is allowed even if you opened the box at three lines.

The ambient-root trap on BuInput applies here too. A sibling BuHelp validation is empty unless the field is wrapped in <InputRoot renderless> — the textarea still paints is-danger, the help stays blank.

Props

PropTypeDefaultDescription
v-modelstring''Field value
v-model:focusedbooleanfalseFocus state
color'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger'is-{color}
disabledbooleanfalseDisables the textarea
errorbooleanfalseForce the invalid state — paints is-danger
error-messagesstring | string[]Manual errors, merged with rule errors
fixedbooleanfalsehas-fixed-size — disables resize
formstringId of the form to associate with
idstring | numberautoTextarea id; generated when omitted
labelstringAccessible name
namestringForm field name
namespacestring'v0:input:root'Context namespace the control binds to
readonlybooleanfalseTextarea stays focusable; value cannot change
requiredbooleanMarks the field required
rulesValidationRule[]Validation rules
size'small' | 'normal' | 'medium' | 'large'is-{size} — omitted until passed
validate-onValidateOnWhen validation runs. v0 default is 'blur'

Inside an ambient Input.Root, every behavioral row in that table is ignored. Native attributes (placeholder, rows, maxlength, …) fall through to the textarea.

Accessibility

The control is a real <textarea>. Name it with a sibling BuLabel, the label prop, or aria-labelledby. An unnamed field fails the axe label rule.

Naming

Prefer a visible BuLabel over label on the textarea. placeholder is a format hint, not a name — e.g. Hello world tells the reader what a filled box looks like; it does not tell assistive technology what the field is for.

States

StateFocusableSubmittedVisual
readonlyYesYesNative readonly
disabledNoNoNative disabled, Bulma’s disabled treatment
error / failed rulesYesYesis-danger on the textarea; aria-invalid from v0

Validation

Same contract as BuInput. aria-invalid follows isValid === false. BuHelp validation only wires aria-errormessage inside an ambient Input.Root. Without that root the textarea can look invalid and explain nothing.

Was this page helpful?

© 2016-1970 Vuetify, LLC
Services
Ctrl+/