Skip to content

Textarea <textarea>

Textareas let users enter and edit multi-line text.

HTML tag<textarea>
Native
Progressive
Plain
Shadow-DOM
Native element
html
<l-form-field>
  <label>Message</label>
  <textarea
    rows="4"
    placeholder="Tell us what's on your mind…"
  ></textarea>
  <p class="l-hint">We usually reply within a day.</p>
</l-form-field>

l-form-field auto-styles a bare <textarea> and wires the accessibility (label, hint, error, aria-*). Standalone, apply .l-textarea to the textarea yourself.

Options

Rows

The native rows attribute sets the initial height; the textarea never shrinks below one control line.

We usually reply within a day.

Code
html
<l-form-field class="max-w-sm">
  <label>Message</label>
  <textarea
    rows="4"
    placeholder="Tell us what's on your mind…"
  ></textarea>
  <p class="l-hint">We usually reply within a day.</p>
</l-form-field>

Resize

data-resize controls the resize handle: vertical (default), none, both, or auto. auto grows the box with its content and hides the handle — where field-sizing is unsupported it keeps the rows height.

Code
html
<div class="grid gap-4 max-w-sm">
  <l-form-field>
    <label>Vertical (default)</label>
    <textarea
      rows="3"
      placeholder="Drag the bottom edge to resize…"
    ></textarea>
  </l-form-field>
  <l-form-field>
    <label>None</label>
    <textarea
      data-resize="none"
      rows="3"
      placeholder="Fixed height"
    ></textarea>
  </l-form-field>
  <l-form-field>
    <label>Auto</label>
    <textarea
      data-resize="auto"
      rows="2"
      placeholder="Grows as you type…"
    ></textarea>
  </l-form-field>
</div>

States

Native disabled and readonly. Invalid is styled via :user-invalid (after interaction) or by setting aria-invalid="true" — inside l-form-field this is managed for you.

Please enter a message.

Code
html
<div class="grid gap-4 max-w-sm">
  <l-form-field>
    <label>Default</label>
    <textarea
      rows="3"
      placeholder="Placeholder text"
    ></textarea>
  </l-form-field>
  <l-form-field>
    <label>Read-only</label>
    <textarea
      rows="3"
      readonly
    >
Read-only value</textarea
    >
  </l-form-field>
  <l-form-field>
    <label>Disabled</label>
    <textarea
      rows="3"
      disabled
    >
Disabled value</textarea
    >
  </l-form-field>
  <l-form-field>
    <label>Invalid</label>
    <textarea
      rows="3"
      required
      aria-invalid="true"
      placeholder="Placeholder text"
    ></textarea>
    <p class="l-error">Please enter a message.</p>
  </l-form-field>
</div>

Size

data-size maps the single-line min-height to the shared control scale (xsxl, default md); the padding scales with it.

Code
html
<div class="grid gap-4 max-w-sm">
  <textarea
    class="l-textarea"
    data-size="xs"
    rows="2"
    placeholder="Extra small"
  ></textarea>
  <textarea
    class="l-textarea"
    data-size="sm"
    rows="2"
    placeholder="Small"
  ></textarea>
  <textarea
    class="l-textarea"
    data-size="md"
    rows="2"
    placeholder="Medium"
  ></textarea>
  <textarea
    class="l-textarea"
    data-size="lg"
    rows="2"
    placeholder="Large"
  ></textarea>
  <textarea
    class="l-textarea"
    data-size="xl"
    rows="2"
    placeholder="Extra large"
  ></textarea>
</div>

Radius

Override --border-radius for the corners.

Accessibility

Criteria

Accessible name

Must have an associated <label> (wrap the textarea or use for/id)

WCAG1.3.1
RGAA11.1
Focus visible

Keyboard focus shows a 2px outline via :focus-visible

WCAG2.4.7
RGAA10.7
Errors identified

aria-invalid marks the field; pair it with a visible message linked via aria-describedby

WCAG3.3.1
RGAA11.10
Required state

Native required communicates a mandatory field to assistive tech

WCAG3.3.2
RGAA11.10

Keyboard interactions

Tab
Moves focus to the textarea
Enter
Inserts a line break (does not submit the form)

API reference

Importing

css
@import 'luxen-ui/css/textarea';

The textarea is CSS-only — no JavaScript import.

Attributes & Properties

rowsAttribute
Number of visible text lines — sets the initial height.
data-sizexs | sm | md | lg | xlAttribute
Single-line min-height on the shared --l-size-control-* scale (default md). Affects only the control, not the label or hint/error.
data-resizevertical | none | both | autoAttribute
User resize handle. Defaults to vertical. auto grows the box with its content via field-sizing (progressive: falls back to the rows height where unsupported).
placeholderAttribute
Native placeholder text.
disabledAttribute
Disables the textarea.
requiredAttribute
Marks the textarea as required for form submission.
readonlyAttribute
Makes the textarea read-only.
maxlengthAttribute
Native maximum character count.
aria-invalidAttribute
Set to true to force the invalid style (otherwise applied via :user-invalid). l-form-field manages this automatically.

CSS classes

.l-textareaClass
Base textarea style, applied to a <textarea>. Inside l-form-field a bare textarea is auto-styled, so the class is optional there.

CSS custom properties

--heightdefault:var(--l-form-control-height)Custom property
Single-line min-height; rows grows the control from here.
--border-radiusdefault:var(--l-form-control-border-radius)Custom property
Control border radius.