Text area

Figma logo The guideline content on this page is synced with Figma and can be used as a source of truth. Open in Figma

Text areas are designed for multi-line input.


Anatomy

  1. Label
  2. Mandatory (optional)
  3. Container
  4. Helper text
  5. Resize indicator
  6. Character count
  7. Info icon (optional)
Text area anatomy diagram showing the 7 component parts

States

  1. Enabled
  2. Hover
  3. Selected
  4. Focused
  5. Error
  6. Error focused
  7. Disabled
  8. Read only
0 /120
Change this to a short description
0 /120
Change this to a short description
0 /120
Change this to a short description
0 /120
Change this to a short description
0 /120
Change this to a short description
0 /120
Change this to a short description
0 /120
Change this to a short description
0 /120
Change this to a short description

Label

A label is mandatory for all text areas and should describe the field's purpose. Labels are included by default. If another element (such as a section title) already serves as a clear description, the default label can be visually hidden.

0 /120
Change this to a short description

Required/optional fields

We use an asterisk to indicate a field is required. The convention of using a red asterisk (*) in a label to denote a required field is a long-standing and widely adopted practice in User Experience (UX) and form design.

0 /120
0 /120

Helper text

Helper text communicates requirements and disclaimers below the field. An error message will always replace the helper text when a field validation error is triggered.

0 /120
Change this to a short description

Character count

A character counter appears whenever there is a limit on the text input. The counter updates in real-time as the user types.

0 /120
Change this to a short description

Resize

Text area fields automatically include a browser-added resize indicator in the lower right. Users can drag this corner to dynamically change the field's dimensions (width and height). This feature should be disabled when the resizing behaviour negatively impacts the layout.

Text area with resize indicator highlighted

Error message

An error message appears beneath a field when the user either leaves a required field empty or submits an invalid value. This message replaces any existing helper text.

0 /120
Change this to a short description

Accessibility

Keyboard interaction

All text areas should be reachable via Tab and Shift+Tab keys.

0 /120
Change this to a short description

Specs

Text area specifications with spacing and radius annotations

Developer reference

The following sections describe supported functionality that is not part of the Figma design specification.

Demo enabled on this page! The enhanced keyboard-focus behaviour is active on this page — the .keyboard-focus class is added to each .form-group while a control is keyboard-focused, and removed on blur, click or typing. Try pressing Tab to navigate through the form fields. Read more in the Forms accessibility guidelines.


Tab vs click focus

New in 2.5

Textareas paint two visually distinct focus states depending on how focus arrived:

  • Click places the caret and paints a 1 px purple Selected border (cursor-active).
  • Tab paints a 2 px blue Focused border (tabbed-in but not yet interacted with).

The runtime distinction is driven by keyboard-focus.js, which adds .keyboard-focus to the parent .form-group while the user is keyboard-navigating and removes it on click or typing. Without .keyboard-focus, :focus always paints the Selected look — so the same CSS selector evaluates to two different appearances.

The static .focus and .selected helper classes mirror these two looks for documentation chips and JS-driven state demos:

  • .focus → 2 px blue (keyboard-focused look)
  • .selected → 1 px purple (mouse-focused / cursor-active look)

Try clicking into the example on the right, then tabbing in and out — the border colour and width will change accordingly.

0 /120
Change this to a short description

Textarea wrapper

New in 2.5

The .textarea-wrapper is a positioning shell used only when a character counter overlay is needed. It provides the position: relative flex container the .textarea-counter anchors to so the counter can sit inside the textarea's visual box.

The <textarea> itself owns all of its visual styling — borders, background, border-radius, focus ring, hover, selected, disabled, readonly, and error states. State classes (.hover, .selected, .focus, .disabled, .readonly) belong on the textarea, not the wrapper.

Use the wrapper when you need a counter; use a plain <textarea class="form-control"> when you don't.

With wrapper (counter overlay)

0 /120
Change this to a short description

Without wrapper

Change this to a short description

Character count implementation

Use the native maxlength attribute on the <textarea> to enforce the limit.

The character count requires JavaScript to update in real-time. The design system provides the CSS styling only — the consuming application is responsible for implementing the counting logic and updating the .textarea-counter-current element.

Implementation guidance

The recommended pattern for framework components (React, Angular, Vue, etc.) is to check the maxlength attribute on the <textarea> element. If maxlength is present, wrap the textarea in .textarea-wrapper, render the .textarea-counter element next to it, and update the current count on input. If maxlength is absent, omit both the wrapper and the counter — a plain <textarea class="form-control"> is sufficient.

0 /120
Change this to a short description

Without counter

Change this to a short description

Accessibility implementation

Always associate a <label> with the <textarea> using matching for and id attributes.

0 /120
Change this to a short description

Info icon

Wrap the <label> and an icon <button> in .label-with-info to place the info icon beside the label with the 8 px gap from the Figma anatomy. On hover or keyboard focus, the tooltip opens upwards (data-bs-placement="top") to reveal the supporting text.

Keep the button outside the <label for> so clicking the icon does not focus the textarea, and mirror the tooltip text into a visually-hidden element that the textarea references via aria-describedby — that way assistive tech users hear the same help text without depending on the tooltip.

Tooltip behaviour relies on Bootstrap's tooltip plugin (with Popper for positioning). See the Tooltips page for setup details.

0 /120
Change this to a short description Provide a clear, concise description so users understand what to enter.

Basic design

Default

A basic text area with a label. Apply the .form-control class to the <textarea> element. Use the rows attribute to set the initial visible height.

0 /120
Change this to a short description

Additional examples

The following examples are also used by our Playwright CSS property assertion tests.

Keyboard focus — wrapped vs bare textarea

Demonstrates the keyboard-focus indicator on both wrapped and bare textareas, including error states.

0 /120
0 /120