Textarea
On this page
Importing
Add rh-textarea to your page with this import statement:
<script type="module">
import '@rhds/elements/rh-textarea/rh-textarea.js';
</script>
Copy to Clipboard
Copied!
Wrap lines
Overflow lines
To learn more about installing RHDS elements on your site using an import map read our getting started docs.
Usage
<label for="my-textarea">
Notes
</label>
<rh-textarea id="my-textarea" placeholder="Enter your notes here"></rh-textarea>
<script type="module">
import '@rhds/elements/rh-textarea/rh-textarea.js';
</script>
<style>
label,
rh-textarea {
margin-inline: 20px;
max-inline-size: 320px;
}
label {
display: block;
font-family: var(--rh-font-family-body-text);
font-weight: var(--rh-font-weight-body-text-medium, 500);
margin-block: var(--rh-space-md, 8px);
}
</style>
Copy to Clipboard
Copied!
Wrap lines
Overflow lines
Validation and error state
Built-in validation
When users set the required property and the textarea is empty, the component participates in the Constraint Validation API. It sets internal validity states (valueMissing, tooShort, tooLong), so the browser can show validation messages when the user submits the form or when you call reportValidity(). Use checkValidity() or reportValidity() on the <rh-textarea> element to validate before submit.
The component validates:
required— value must not be emptyminlength— value must meet the minimum character countmaxlength— value must not exceed the maximum character count
See the Required demo for an example of this functionality.
Custom validation and error state
This component does not set aria-invalid when setting state="danger". For custom errors, you should:
- Visual state: Set
state="danger"andhelp-text="My error message"with the error message. - Semantic state for assistive tech: Set
aria-invalid="true"on the<rh-textarea>host element so screen readers announce the invalid state. - Blocking form submit: The component only sets validity for
required,minlength, andmaxlength. For custom rules, handle submit yourself:- In your submit handler, run your custom check.
- If the check fails: call
preventDefault()so the form does not submit then setstate="danger",help-text, andaria-invalid="true"so the user sees and hears the error. - If the check passes: clear the error state and allow the form to submit.
Example: validate on submit and show a custom error state when the textarea content fails a rule.
<form id="my-form">
<label for="notes">Notes</label>
<rh-textarea id="notes" name="notes" placeholder="Enter your notes"></rh-textarea>
<button type="submit">Submit</button>
</form>
<script type="module">
import '@rhds/elements/rh-textarea/rh-textarea.js';
const form = document.getElementById('my-form');
const textarea = document.getElementById('notes');
form.addEventListener('submit', (e) => {
if (textarea.value.includes('forbidden')) {
e.preventDefault();
textarea.setAttribute('state', 'danger');
textarea.setAttribute('help-text', 'Text contains a forbidden word.');
textarea.setAttribute('aria-invalid', 'true');
textarea.focus();
} else {
textarea.removeAttribute('state');
textarea.removeAttribute('help-text');
textarea.removeAttribute('aria-invalid');
}
});
</script>
For accessibility implications and why the component does not set aria-invalid from state, see Validation and error state in the Textarea accessibility documentation.
ARIA attributes
Always set ARIA attributes on the host element, not on the inner textarea — the host is the form-associated custom element and the browser exposes its ARIA attributes via ElementInternals.
rh-textarea
A textarea element allows users to enter multi-line text.
It functions as a branded, accessible <textarea> element with
cross-root ARIA wiring, form association, and constraint validation.
Theming
This element uses Red Hat design system theming and can be used in themable contexts.
Slots
1
| Slot Name | Summary | Description |
|---|---|---|
help-text
|
Help or error text displayed below the textarea.
Overrides the |
Attributes
21
| Attribute | DOM Property | Description | Type | Default |
|---|---|---|---|---|
accessible-label
|
accessibleLabel |
Accessible name when no external |
|
|
autocomplete
|
autocomplete |
Browser autocomplete hint forwarded to the inner textarea. |
|
|
cols
|
cols |
Visible width in average character widths. |
|
|
disabled
|
disabled |
Whether the textarea is disabled. Uses |
|
|
field-sizing
|
fieldSizing |
When set to |
|
|
help-text
|
helpText |
Help text displayed below the control. Content slotted into the help-text slot overrides this attribute. |
|
|
value-missing-message
|
valueMissingMessage |
Validation message shown when |
|
|
too-short-message
|
tooShortMessage |
Validation message shown when the value is shorter than |
|
|
too-long-message
|
tooLongMessage |
Validation message shown when the value exceeds |
|
|
maxlength
|
maxlength |
Maximum number of characters (UTF-16 code units) allowed. |
|
|
minlength
|
minlength |
Minimum number of characters (UTF-16 code units) required. |
|
|
name
|
name |
The name of the control, used for form submission. |
|
|
placeholder
|
placeholder |
Placeholder hint text shown when the textarea is empty. |
|
|
readonly
|
readonly |
Whether the textarea is read-only. Value is still submitted. |
|
|
required
|
required |
Whether a value is required before form submission. Syncs to aria-required and constraint validation. |
|
|
resize
|
resize |
Controls whether the textarea is resizable by the user.
Mapped to the CSS |
|
|
rows
|
rows |
Number of visible text lines. Defaults to 5 for a comfortable editing area, matching the ux.redhat.com form pattern sizing. |
|
|
show-character-count
|
showCharacterCount |
Opt-in character counter. Only renders when both this attribute
and |
|
|
state
|
state |
Visual and semantic state of the form control for user feedback.
Use 'danger' for blocking errors, 'warning' for non-blocking
issues, and 'success' for valid input. Affects styling only;
does not set |
|
|
value
|
value |
Current value of the textarea. Not reflected to an attribute. |
|
|
wrap
|
wrap |
How the textarea wraps text for form submission. |
|
|
Methods
5
| Method Name | Description |
|---|---|
checkValidity()
|
Returns true if the element's value passes constraint validation. Updates validity state before checking. |
reportValidity()
|
Returns true if the element's value passes constraint validation. If invalid, reports the problem (e.g. browser tooltip) and returns false. |
select()
|
Selects all text in the textarea. |
setRangeText(replacement: string, start: number, end: number, selectMode: SelectionMode)
|
Replaces a range of text. Defaults start/end to current selection when not provided (matching the Shoelace fix for this edge case). |
setSelectionRange(start: number | null, end: number | null, direction: 'forward' | 'backward' | 'none')
|
Sets the cursor position or text selection range. |
Events
0
None
CSS Shadow Parts
1
| Part Name | Summary | Description |
|---|---|---|
textarea
|
The inner native |
CSS Custom Properties
4
| CSS Property | Description | Default |
|---|---|---|
--rh-textarea-resize-direction |
Sets the resize direction for the textarea / input. Overridden by |
vertical
|
--rh-color-status-disabled |
light-dark(
var(--rh-color-gray-30, #c7c7c7),
var(--rh-color-gray-40, #a3a3a3))
|
|
--rh-color-text-status-disabled |
light-dark(
var(--rh-color-gray-50, #707070),
var(--rh-color-gray-60, #4d4d4d))
|
|
--rh-textarea-icon-size |
14px
|
Design Tokens
32
| Token | Description | Copy |
|---|---|---|
--rh-font-family-body-text
|
Textarea font family Body text font family |
|
--rh-font-weight-body-text-regular
|
Textarea font weight Regular font weight |
|
--rh-line-height-body-text
|
Textarea line height Line height for body text |
|
--rh-color-surface-lightest
|
Input surface color for light schemes Primary surface (light theme) |
|
--rh-color-surface-darkest
|
Input surface color for dark schemes Primary surface (dark theme) |
|
--rh-border-width-sm
|
Input border width 1px border width; Example: Secondary CTA or Button |
|
--rh-color-border-subtle
|
Input border color |
|
--rh-border-radius-default
|
Default border radius 3px border radius; Example: Card |
|
--rh-color-text-primary
|
Textarea text color Input text color |
|
--rh-space-lg
|
Left and right padding for input 16px spacer |
|
--rh-border-width-lg
|
Outer focus ring width when focused 3px border width: Example: Expanded Accordion panel |
|
--rh-color-border-interactive
|
Input hover border color Textarea border color when focused Outer focus ring color when focused |
|
--rh-color-gray-30
|
Subtle borders (light theme) |
|
--rh-color-gray-40
|
Subtle icon (hover state) |
|
--rh-color-gray-50
|
Subtle icon |
|
--rh-color-gray-60
|
Secondary text (light theme) |
|
--rh-color-surface-lighter
|
Readonly surface color for light schemes Tertiary surface (light theme) |
|
--rh-color-surface-darker
|
Readonly surface color for dark schemes Secondary surface (dark theme) |
|
--rh-color-gray-20
|
Readonly border in light schemes Secondary surface (light theme) |
|
--rh-color-gray-70
|
Readonly border in dark schemes Tertiary surface (dark theme) |
|
--rh-color-text-secondary
|
Textarea placeholder text color Secondary text color for the character counter |
|
--rh-font-size-body-text-xs
|
Extra-small font size for the character counter 12px font size |
|
--rh-space-md
|
Top and bottom padding for input Block start margin for the character counter Help text CSS gap Help text margin-block-start 8px spacer |
|
--rh-font-size-body-text-sm
|
Textarea text size Help text slotted elements font size 14px font size |
|
--rh-color-border-status-success
|
|
|
--rh-color-border-status-warning
|
|
|
--rh-color-border-status-danger
|
|
|
--rh-font-weight-body-text-medium
|
Medium font weight |
|
--rh-color-icon-status-success
|
Success icon color design token for the help-text status indicator |
|
--rh-color-icon-status-warning
|
Warning icon color design token for the help-text status indicator |
|
--rh-color-icon-status-danger
|
Danger icon color design token for the help-text status indicator |
|
--rh-length-6xl
|
96px length token |
|
Other libraries
To learn more about our other libraries, visit this page.
Feedback
To give feedback about anything on this page, contact us.