Text area
Text areas allow users to enter and edit multi-line text. They typically appear in forms.
<sl-text-area aria-label="Hobbies" value="Painting, drawing, dance..."></sl-text-area>When to use
The following guidance describes when to use the text area component.
Unconstrained input
When you need to collect input that can be of variable length, such as comments, descriptions, or notes. Use a text area when the newline character (line break) is a valid part of the content.
When not to use
The following guidance describes when not to use the text area component.
Single-line input
If the input is expected to be short and concise, consider using a text field component instead of a Text Area. For instance, when collecting a username or password a single-line input is more appropriate.
Anatomy
| Item | Name | Description | Optional |
|---|---|---|---|
| 1 | Input container | An interactive input area. | No |
| 2 | Input & placeholder text | Input text is a value the user has entered into an input and the placeholder text is a short hint that describes the expected value of an input. | No |
| 3 | Caret | A thin vertical line that blinks to indicate where input will be inserted. | No |
| 4 | Resize handle | An indicator that appears in the bottom right corner of the input container. | No |
Figma Options
With these options, you can tweak the appearance of the text area in Figma. They are available in the Design Panel so you can compose the text area to exactly fit the user experience need for the use case you are working on.
Text Area
| Item | Options | Description |
|---|---|---|
| Size | md lg | The text area come in two sized medium (default) and large. |
| State | default valid invalid | To indicate the state of the text area. |
| Filled | boolean | To indicate if the text area is filled or displays a placeholder. |
| Input text | value | To insert the text of the filled text or placeholder. |
Label
| Item | Options | Description |
|---|---|---|
| Label | boolean | To display a label. |
| Size | sm md lg | The label come in three sizes small, medium (default) and large. |
| Disabled | boolean | To show the disabled state of the label. |
| Required | boolean | Indicates if the text area is required. |
| Optional | boolean | Indicates if the text area is optional. |
| Info | boolean | To show a info icon with tooltip after the label. |
| Text | value | To insert the text of the label. |
Hint
| Item | Options | Description |
|---|---|---|
| Hint | boolean | To display the hint. |
| Size | sm md lg | The label come in three sizes small, medium (default) and large. |
| State | default disabled invalid | To indicate the state of the hint. |
| Icon | boolean | Displays an icon in front of the hint. |
| Text | value | To insert the text of the hint. |
Focus ring
| Item | Options | Description |
|---|---|---|
| Focus ring | boolean | To display the focus state of the text area. |
Behaviours
Character limit
Use show-count to display a soft character limit. It shows remaining characters and updates as users type or paste content. At 10% remaining, it switches to a caution style. When exceeded, it shows how many characters must be removed and marks the Text Area as invalid.
Users can exceed the limit, but validation replaces the counter with an error message. Screen readers announce changes only when moving between default, caution, and danger states.
Do not combine show-count with maxlength, which blocks extra input. Also, use minlength character limits carefully, as it can create unnecessary constraints and confusion for users, and avoid using minlength together with maxlength because it may lead to repeated trial-and-error to meet both constraints instead of focusing on the quality of their input.
Resizing
By default, the Text Area can be resized vertically, meaning users can drag its bottom edge to make it taller if they need more space. The rows setting determines how tall the Text Area appears when it first loads. You can use resize="auto" to let it grow automatically as content is added, or resize="none" to keep its height fixed.
Validation
Supports required, min/max length, and custom validation, with feedback appearing when validity is reported. Required fields are invalid when empty, minimum length applies after input begins, and custom validation can be synchronous or asynchronous, with final results withheld until asynchronous checks complete.
<sl-text-area aria-label="My favourite subject" value="My favourite subject is..."></sl-text-area>API
Component has a range of properties to define the experience in different use cases.
Properties
| Name | Attribute | Type | Default | Description |
|---|---|---|---|---|
autocomplete | autocomplete | typeof HTMLTextAreaElement.prototype.autocomplete | undefined | Specifies which type of data the browser can use to pre-fill the textarea. NOTE: Declare the type this way so it is backwards compatible with 4.9.5, which we still use in | |
customValidity | custom-validity | string | undefined | The error message to display when the control is invalid. | |
dirty | - | boolean | false | A control is dirty if the user has changed the value in the UI. |
disabled | disabled | boolean | undefined | Whether the textarea is disabled; when set no interaction is possible. | |
form | - | HTMLFormElement | null | The form associated with the control. | |
formValue | - | unknown | The value used when submitting the form. | |
labels | - | | The labels associated with the control. | |
maxLength | maxlength | number | undefined | Maximum length (number of characters). Not recommended from a UX perspective, because it blocks additional typing once the limit is reached and can cut off pasted text. Prefer showCount to allow users to type or paste beyond the limit and then revise input. | |
minLength | minlength | number | undefined | Minimum length (number of characters). Not recommended from a UX perspective. | |
name | name | string | undefined | The name of the form control. | |
nativeFormValue | - | FormValue | Returns the form value as used in a native <form>. This is always a string, File, FormData or null. | |
placeholder | placeholder | string | undefined | Placeholder text in the textarea. | |
readonly | readonly | boolean | undefined | Whether you can interact with the textarea or if it is just a static, readonly display. | |
required | required | boolean | undefined | Whether the textarea is a required field. | |
resize | resize | 'none' | 'vertical' | 'auto' | 'vertical' | The way the textarea can be resized. |
rows | rows | number | undefined | The number of rows the textarea should have. For resize auto and vertical, this will determine the minimum height of the textarea. If not set, the component defaults to 3 rows. | |
showCount | show-count | number | undefined | The maximum number of characters allowed (soft limit). When set, a character counter appears below the textarea showing how many characters remain. When 90% of the limit is reached the counter turns caution (orange). When the limit is exceeded it turns to a danger state, shows how many characters are over the limit, and marks the textarea as invalid. Exceeding the limit does not block input, the user can still type or paste more text and then edit it down. Please don't combine | |
showValid | show-valid | boolean | false | When set will cause the control to show it is valid after reportValidity is called. |
showValidity | show-validity | 'valid' | 'invalid' | undefined | Whether to show the validity state. | |
size | size | 'md' | 'lg' | undefined | md | The size of the textarea. |
textarea | - | HTMLTextAreaElement | The textarea in the light DOM. | |
touched | - | boolean | false | A control is marked touched once the user has triggered a blur event on it. |
valid | - | boolean | Returns whether the form control is valid or not. | |
validationMessage | - | string | String representing a localized (by the browser) message that describes the validation constraints that the control does not satisfy (if any). The string is empty if the control is not a candidate for constraint validation, or it satisfies its constraints. For true localization, see | |
validity | - | ValidityState | Returns the validity state the control is in. | |
validityState | - | 'valid' | 'invalid' | 'pending' | Returns the current validity state. | |
value | value | unknown | undefined | '' | The value for the textarea. |
wrap | wrap | 'soft' | 'hard' | 'soft' | The way text should be wrapped during form submission. |
Methods
| Name | Parameters | Return | Description |
|---|---|---|---|
focus | void | ||
reportValidity | boolean | Returns whether the control is valid. If the control is invalid, calling this will also cause an invalid event to be dispatched. After calling this, the control will also report the validity to the user. | |
getLocalizedValidationMessage | string | This returns a localized validation message. It does not support all ValidityState properties, since some require more context than we have here. If you need to support more, you can override this method in your own form control. | |
updateInternalValidity | void | Sets or clears the character count custom validity error. Only clears the error if we set it ourselves, so we never accidentally overwrite a custom error set by the user. | |
setCustomValidity | message: string | Promise<string> | void | Override setCustomValidity to reset the count validity flag whenever an external custom error is set. This ensures the component can distinguish between errors it set itself and errors set externally by consumers. |
Events
| Name | Event type | Description |
|---|---|---|
sl-blur | SlBlurEvent | Emits when the focus leaves the component. |
sl-change | SlChangeEvent<string> | Emits when the value changes. |
sl-focus | SlFocusEvent | Emits when the component gains focus. |
sl-form-control | SlFormControlEvent | Emits when the form control is added to the DOM. |
sl-update-state | SlUpdateStateEvent | Emits when the UI state (dirty, pristine, touched or untouched) of the form control changes. |
sl-update-validity | SlUpdateValidityEvent | Emits when the validity of the form control changes. |
sl-validate | SlValidateEvent | Emits when the form control can be validated. |
Slots
| Name | Description |
|---|---|
textarea | The slot for the textarea element. |
Keyboard interactions
Here's an overview of the common keyboard interactions associated with a text area:
| Command | Description |
|---|---|
| Tab | When focus is outside the text area, moves focus to the input container. If focus is on the input container, moves focus to the end enhancer (if provided, and interactive). |
WAI-ARIA
In the component itself we use multiple aria-attributes to assure the component works well with a range of assistive technologies. For some attributes however it is not possible for the Design System to add a meaningful value, because it relies on the context or way a component is used.
Attributes that we recommend you add in certain scenarios are mentioned below.
| Attribute | Value | Description |
|---|---|---|
aria-label | string | Defines a string that tells the user what information they need to enter in this text area. Needs to be added when the text area is not wrapped with sl-form-field and there is no sl-label. |
aria-labelledby | string | Used to connect with single header/element that describes the text area, when there is no label component connected to. |
aria-required | boolean | Informs the user that an element is required. When set to ‘true’, screen readers notify users that the element is required. If there is already a required attribute added, it is recommended to avoid adding aria-required. |
aria-disabled | boolean | Announces the text area component as disabled with a screen reader. See [Note 1] below. |
Notes:
- The
aria-disabledshould not be used as a one-for-one replacement for thedisabledattribute because they have different functionalities:
disableddims the text area visually, takes it out of the tab-focus sequence, prevents actions (click, enter) on it and announces it as 'dimmed' or 'disabled' in a screen reader.aria-disabledonly does the latter. You will need to disable the functionality yourself. This might be useful for scenarios where you don't want to take the text area out of the navigation flow.
When disabled is added to a text area there is no need to also add aria-disabled. Everything aria-disabled does, disabled does as well. You can read more on the difference and in which scenarios which option might be preferable on the MDN page about aria-disabled.