Skip to content

Textarea

A custom-styled textarea component extending HTMLTextAreaElement.

The component builds a [field-wrapper] span around the control - always, with or without a label - and that span carries the field box; the <label> and the hint are its siblings.

Usage

<textarea is="root-textarea" placeholder="Write something..." data-label="Message"></textarea>

Resize

data-resize names the axis the native handle may move on: vertical (the default), horizontal, both or none. The [field-wrapper] takes the control's own size, so whatever the user drags it to is the size of the box around it.

<textarea is="root-textarea" data-label="Vertical" data-resize="vertical"></textarea>
<textarea is="root-textarea" data-label="Horizontal" data-resize="horizontal"></textarea>
<textarea is="root-textarea" data-label="Both" data-resize="both"></textarea>
<textarea is="root-textarea" data-label="Fixed" data-resize="none"></textarea>

Hint and error

data-hint holds the description and data-error the error message: both are authored once, and data-invalid decides which one shows. With no data-error the browser's own validationMessage stands in. One node carries both, wired to the control through aria-describedby.

<textarea is="root-textarea" data-label="Bio" data-hint="A short bio" data-error="Too long"></textarea>

No-autofill

Add no-autofill to opt a field out of native autocomplete/autocorrect/ autocapitalize/spellcheck and the common password-manager browser extensions (1Password, LastPass, Bitwarden) - none of which honor a single standard attribute.

<textarea is="root-textarea" no-autofill data-label="One-time note"></textarea>

Sizes

data-size takes small and large; medium is the default and needs no value written. The step moves the padding and the minimum height; the text stays at the base step at every size, which is the floor under which iOS Safari zooms the viewport on focus.

<textarea is="root-textarea" data-size="small" data-label="Small" rows="2"></textarea>
<textarea is="root-textarea" data-label="Medium" rows="2"></textarea>
<textarea is="root-textarea" data-size="large" data-label="Large" rows="2"></textarea>

Attributes

Attribute Type Default Description
placeholder string - Placeholder text
rows number - Visible rows
data-resize 'vertical' | 'horizontal' | 'both' | 'none' 'vertical' Which axis the resize handle moves on
no-autofill boolean false Opt out of autocomplete and password managers
disabled boolean false Disables the textarea
readonly boolean false Read-only state
data-label string - Label text; the component builds the <label>
required boolean false Marks the field required and draws the asterisk
data-hint string - Description shown under the field
data-error string - Error message; falls back to validationMessage
data-invalid 'true' - Shows the error instead of the description

Events

Namespaced as <component>.<event>, bubbling and cancelable; detail also carries the originating DOM event as originalEvent.

Event Detail Description
root-textarea.input { value } Fired on input
root-textarea.change { value } Fired on change
root-textarea.focus { value } Fired on focus
root-textarea.blur { value } Fired on blur
root-textarea.invalid { value } Fired when the control fails constraint validation
root-textarea.data-label.change { value, oldValue } Fired when the label text changes

Extends

HTMLTextAreaElement - use with <textarea is="root-textarea">.