Textarea

Specs: DESIGN.md line 444-458

Default

<textarea
  class="elv-textarea"
  placeholder="Enter your message..."
  aria-label="Message"
></textarea>

With Label & Helper Text

Include as much detail as possible to help us understand your needs.

Optional: Add any extra context that might be helpful.

<label class="elv-textarea-label" for="description">
  Description <span class="elv-required">*</span>
</label>
<textarea
  id="description"
  class="elv-textarea"
  placeholder="Provide a detailed description..."
  required
  aria-required="true"
></textarea>
<p class="elv-textarea-helper">
  Helper text goes here
</p>

With Character Count

0 / 500

Maximum 500 characters

0 / 1000
<div class="elv-textarea-wrapper">
  <textarea
    maxlength="500"
    oninput="updateCount(this)"
  ></textarea>
  <span class="elv-char-count">0 / 500</span>
</div>

<script>
function updateCount(textarea) {
  const count = textarea.value.length;
  const max = textarea.maxLength;
  const counter = textarea.nextElementSibling;
  counter.textContent = `${count} / ${max}`;
}
</script>

Focus State

Focus state: 3px light purple outline (#c3bde5) — CRITICAL for accessibility

Simulated focus state (for reference):

.elv-textarea:focus {
  outline: 3px solid #c3bde5; /* P40 */
  outline-offset: 1px;
}

Error State

<textarea
  class="elv-textarea elv-textarea--error"
  aria-invalid="true"
  aria-describedby="error-message"
></textarea>
<p id="error-message" class="elv-textarea-error" role="alert">
  Error message text
</p>

Disabled State

This field is not currently editable.

<textarea class="elv-textarea" disabled></textarea>

Resizable Demo

↕️ Drag the bottom-right corner to resize vertically (horizontal resize is disabled)

Custom min-height can be set via inline styles or custom classes.

<!-- Default (min-height: 80px) -->
<textarea class="elv-textarea"></textarea>

<!-- Custom height -->
<textarea class="elv-textarea" style="min-height: 200px;"></textarea>

/* CSS */
.elv-textarea {
  resize: vertical; /* Only vertical resize */
  min-height: 80px; /* Default minimum */
}

Complete Form Example

0 / 2000

Please provide as much detail as possible. Maximum 2000 characters.

Code Snippets

Basic Textarea

<textarea
  class="elv-textarea"
  placeholder="Enter text..."
  aria-label="Description"
></textarea>

With Label (Required)

<label class="elv-textarea-label" for="message">
  Message <span class="elv-required">*</span>
</label>
<textarea
  id="message"
  class="elv-textarea"
  required
  aria-required="true"
></textarea>

With Character Count

<div class="elv-textarea-wrapper">
  <textarea
    class="elv-textarea"
    maxlength="500"
    oninput="updateCount(this)"
  ></textarea>
  <span class="elv-char-count">0 / 500</span>
</div>

Error State

<textarea
  class="elv-textarea elv-textarea--error"
  aria-invalid="true"
  aria-describedby="error-id"
></textarea>
<p id="error-id" class="elv-textarea-error" role="alert">
  Error message
</p>

Custom Height

<textarea
  class="elv-textarea"
  style="min-height: 200px;"
></textarea>

Accessibility Notes

Design System Specs (DESIGN.md)

Background #fafafa (N5)
Border 0.5px solid #b0afb6 (border-medium N40)
Border Radius 8px (radius-sm)
Min Height sm: 52px, md: 64px, lg: 64px
Padding 12px (all sides)
Font 16px / 400 / 24px line-height (Body)
Font Family Figtree (var(--font-sans))
Placeholder #6f6d78 (text-nonessential)
Resize vertical only (no horizontal)
Focus State 3px solid #c3bde5 outline (P40), 1px offset
Error State 2px border #eb2000 (R120), padding 11px
Error Message 12px / 600, #b21800 (R140)
Disabled Background #fcfcfd (N1), text #b0afb6 (N40), no resize
Label 14px / 600, #201f23 (text-default)
Helper Text 12px / 400, #6f6d78 (text-nonessential)
Character Count 12px, #6f6d78, positioned bottom-right

Usage Guidelines