Textarea
Overview
Use a textarea to help a user enter an answer to a question that is likely to be longer than one line. For example, to answer an open-ended question.
A good use of this component is to ask the user for feedback about your service.
Example Textarea contents
Nunjucks
{% from "components/textarea/_macro.njk" import onsTextarea %}
{{
onsTextarea({
"id": "textarea",
"name": "feedback",
"label": {
"text": "Please provide some feedback",
"description": "For example, describe any difficulties you experienced in the use of this service"
}
})
}}
Nunjucks macro options
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the textarea. Sets the HTML for attribute on the label . |
classes | string | false | Classes to add to the textarea |
name | string | false | The HTML name attribute for the textarea |
value | string | false | The HTML value for the textarea to set a preset value for the field |
attributes | object | false | HTML attributes (for example, data attributes) to add to the textarea |
label | object<Label> | false | Settings for the label |
width | string | false | Sets the width of the textarea input by number of characters. See input component for details. |
rows | integer | false | Sets the height of the textarea by number of rows. Defaults to “8”. |
charCheckLimit | Object<CharCheckLimit> | false | Settings for the textarea character limit counter |
mutuallyExclusive | MutuallyExclusive (ref) | false | Settings to use the textarea as a mutually exclusive answer |
fieldId | string | false | The HTML id of the field |
fieldClasses | string | false | Classes for the field |
legend | string | false (unless mutuallyExclusive set) | Text for the fieldset legend |
legendClasses | string | false | Classes for the fieldset legend |
description | string | false | The hint text for the mutually exclusive fieldset |
dontWrap | boolean | false | Set to “true” to prevent the textarea from being wrapped in a field component |
legendIsQuestionTitle | boolean | false | Creates an h1 inside the legend. Use when the mutually exclusive textarea is the only fieldset on the page |
error | Error (ref) | false | Settings for validation errors |
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the component |
limit | integer | true | The maximum number of characters allowed in the input |
charCountPlural | string | true | The string displayed when multiple characters can be entered before the limit is reached. Set {x} in the string to be replaced with the number, for example “You have {x} characters remaining”. |
charCountSingular | string | true | The string displayed when one more character can be entered before the limit is reached. Set {x} in the string to be replaced with the number, for example “You have {x} character remaining”. |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text content of the label |
for | string | true | Set with the HTML id of the textarea the label is for |
description | string | false | Hint text to help users fill in the input |
classes | string | false | Classes to add to the label |
HTML
<div class="ons-field">
<label class="ons-label ons-label--with-description" for="textarea" aria-describedby="description-hint">Please provide
some feedback</label>
<span id="description-hint" class="ons-label__description ons-input--with-description">For example, describe any
difficulties you experienced in the use of this service</span>
<textarea id="textarea" class="ons-input ons-input--textarea" name="feedback" rows="8"></textarea>
</div>
When not to use this component
Open-ended questions can be difficult for users to answer.
Consider breaking down the question into simpler questions that can be using an input or radios.
How to use this component
Labels
All textarea components must have a visible label.
This can be with or without a description.
Appropriate sizing
The size of a textarea should help the user understand what content it was intended for.
By default, the textarea component will fill the width of its container and has a default height of 8 lines of text.
Change the height of a textarea
To change the height of a textarea, use the rows
parameter.
Change the width of a textarea
A textarea will fill 100% of the width of it’s container.
To decrease the width of a textarea, use a width constrained class.
Variants
Character limit
The character limit counter is displayed when the charCheckLimit
object is defined with limit
, charCountSingular
, charCountPlural
parameters.
Example Textarea With Character Limit contents
Nunjucks
{% from "components/textarea/_macro.njk" import onsTextarea %}
{{
onsTextarea({
"id": "textarea-char-limit",
"name": "feedback-limited",
"width": "30",
"label": {
"text": "Please provide some feedback",
"description": "For example, describe any difficulties you experienced in the use of this service"
},
"charCheckLimit": {
"limit": 200,
"charCountSingular": "You have {x} character remaining",
"charCountPlural": "You have {x} characters remaining"
}
})
}}
Nunjucks macro options
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the textarea. Sets the HTML for attribute on the label . |
classes | string | false | Classes to add to the textarea |
name | string | false | The HTML name attribute for the textarea |
value | string | false | The HTML value for the textarea to set a preset value for the field |
attributes | object | false | HTML attributes (for example, data attributes) to add to the textarea |
label | object<Label> | false | Settings for the label |
width | string | false | Sets the width of the textarea input by number of characters. See input component for details. |
rows | integer | false | Sets the height of the textarea by number of rows. Defaults to “8”. |
charCheckLimit | Object<CharCheckLimit> | false | Settings for the textarea character limit counter |
mutuallyExclusive | MutuallyExclusive (ref) | false | Settings to use the textarea as a mutually exclusive answer |
fieldId | string | false | The HTML id of the field |
fieldClasses | string | false | Classes for the field |
legend | string | false (unless mutuallyExclusive set) | Text for the fieldset legend |
legendClasses | string | false | Classes for the fieldset legend |
description | string | false | The hint text for the mutually exclusive fieldset |
dontWrap | boolean | false | Set to “true” to prevent the textarea from being wrapped in a field component |
legendIsQuestionTitle | boolean | false | Creates an h1 inside the legend. Use when the mutually exclusive textarea is the only fieldset on the page |
error | Error (ref) | false | Settings for validation errors |
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the component |
limit | integer | true | The maximum number of characters allowed in the input |
charCountPlural | string | true | The string displayed when multiple characters can be entered before the limit is reached. Set {x} in the string to be replaced with the number, for example “You have {x} characters remaining”. |
charCountSingular | string | true | The string displayed when one more character can be entered before the limit is reached. Set {x} in the string to be replaced with the number, for example “You have {x} character remaining”. |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text content of the label |
for | string | true | Set with the HTML id of the textarea the label is for |
description | string | false | Hint text to help users fill in the input |
classes | string | false | Classes to add to the label |
HTML
<div class="ons-field">
<label class="ons-label ons-label--with-description" for="textarea-char-limit"
aria-describedby="description-hint">Please provide some feedback</label>
<span id="description-hint" class="ons-label__description ons-input--with-description">For example, describe any
difficulties you experienced in the use of this service</span>
<textarea id="textarea-char-limit" class="ons-input ons-input--textarea ons-js-char-limit-input ons-input--w-30"
name="feedback-limited" rows="8" maxlength="200" data-char-limit-ref="textarea-char-limit-lim"
aria-describedby="textarea-char-limit-lim"></textarea>
<span id="textarea-char-limit-lim" class="ons-input__limit ons-u-fs-s--b ons-u-d-no ons-u-mt-2xs"
data-charcount-singular="You have {x} character remaining" data-charcount-plural="You have {x} characters remaining"
data-charcount-limit-singular="" data-charcount-limit-plural="">
</span>
</div>
Mutually exclusive textarea
Use the mutually exclusive variant to let a user give a contrasting answer instead of filling in the textarea.
This macro is called automatically when the mutuallyExclusive
parameter is set, which adds the:
- mutually exclusive checkbox
- required aria-live alert markup
- classes required for the JavaScript to run
Example Mutually Exclusive Textarea contents
Nunjucks
{% from "components/textarea/_macro.njk" import onsTextarea %}
{% from "components/question/_macro.njk" import onsQuestion %}
{%
call onsQuestion({
"title": "What do you think of this service?",
"legendIsQuestionTitle": true
})
%}
{{
onsTextarea({
"id": "feedback",
"name": "feedback",
"dontWrap": true,
"width": "30",
"label": {
"text": "Enter your feedback"
},
"charCheckLimit": {
"limit": 200,
"charCountSingular": "You have {x} character remaining",
"charCountPlural": "You have {x} characters remaining"
},
"mutuallyExclusive": {
"or": "Or",
"deselectMessage": "Selecting this will clear your feedback",
"deselectGroupAdjective": "cleared",
"deselectExclusiveOptionAdjective": "deselected",
"exclusiveOptions": [
{
"id": "feedback-checkbox",
"name": "no-feedback",
"value": "no-feedback",
"label": {
"text": "I don’t want to provide feedback"
}
}
]
}
})
}}
{% endcall %}
Nunjucks macro options
Name | Type | Required | Description |
---|---|---|---|
id | string | false | The HTML id of the fieldset |
classes | string | false | Classes to apply to the fieldset |
legend | string | true (unless legendIsQuestionTitle is set) | Text for the fieldset’s legend |
legendClasses | string | false | Classes to apply to the legend element |
legendIsQuestionTitle | boolean | true (unless legend is set) | Creates an h1 inside the legend . Use when there is only a single fieldset on the page |
description | string | false | Description for the fieldset |
attributes | object | false | HTML attributes (for example, data attributes) to add to the fieldset |
exclusiveOptions | Array<Checkbox> or Array<radio> | true | Configuration for the mutually exclusive options |
or | string | false | Text for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to "Or". |
deselectMessage | string | true | The text the aria-live alert will announce to warn that selecting the exclusive checkbox will clear or unselect all other answer options. For example, ”Selecting this will uncheck all other checkboxes”. |
deselectGroupAdjective | string | true | The text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected |
deselectExclusiveOptionAdjective | string | true | The text the aria-live alert will announce when an option is cleared or unselected when the mutually exclusive checkbox is selected |
error | Error (ref) | false | Configuration for validation errors |
dontWrap | boolean | false | Prevents fields,checkboxes,date input,duration,input and Textarea from being wrapped in a fieldset component |
autosuggestresults | string | false | Shows suggested options to users as they enter something into an input field |
HTML
<div class="ons-question ons-u-mb-xl">
<div class="ons-question__answer ons-u-mb-l">
<fieldset class="ons-fieldset">
<legend class="ons-fieldset__legend ons-u-mb-no">
<h1 id="fieldset-legend-title" class="ons-fieldset__legend-title">What do you think of this service?</h1>
</legend>
<div class="ons-input-items">
<div class="ons-js-mutually-exclusive ons-mutually-exclusive">
<label class="ons-label" for="feedback">Enter your feedback</label>
<textarea id="feedback"
class="ons-input ons-input--textarea ons-js-char-limit-input ons-js-exclusive-group-item ons-input--w-30"
name="feedback" rows="8" maxlength="200" data-char-limit-ref="feedback-lim"
aria-describedby="feedback-lim"></textarea>
<span id="feedback-lim" class="ons-input__limit ons-u-fs-s--b ons-u-d-no ons-u-mt-2xs"
data-charcount-singular="You have {x} character remaining"
data-charcount-plural="You have {x} characters remaining" data-charcount-limit-singular=""
data-charcount-limit-plural="">
</span>
<p class="ons-checkboxes--mutually-exclusive__item ons-u-mt-s">
<span class="ons-checkboxes__label ons-u-fs-r--b" aria-hidden="true">Or</span>
<span class="ons-checkbox">
<input type="checkbox" id="feedback-checkbox"
class="ons-checkbox__input ons-js-checkbox ons-js-exclusive-option" value="no-feedback"
name="no-feedback" data-deselect-message="Selecting this will clear your feedback" />
<label class=" ons-checkbox__label" for="feedback-checkbox" id="feedback-checkbox-label"><span
class="ons-u-vh">Or, </span> I don’t want to provide feedback</label>
</span>
</p>
<span class="ons-js-exclusive-alert ons-u-vh" role="alert" aria-live="polite" data-group-adjective="cleared"
data-option-adjective="deselected"></span>
</div>
</div>
</fieldset>
</div>
</div>
How to check a textarea
To help users enter something in a required textarea:
- check they have entered something in the textarea
- show an error message if they have not entered anything
Error messages
Show the error details above the textarea and use the correct errors pattern.
Example Textarea Error contents
Nunjucks
{% from "components/textarea/_macro.njk" import onsTextarea %}
{{
onsTextarea({
"id": "textarea-error",
"name": "feedback",
"label": {
"text": "Please provide some feedback",
"description": "For example, describe any difficulties you experienced in the use of this service"
},
"error": {
"id": "feedback-error",
"text": "Enter your feedback"
}
})
}}
Nunjucks macro options
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the textarea. Sets the HTML for attribute on the label . |
classes | string | false | Classes to add to the textarea |
name | string | false | The HTML name attribute for the textarea |
value | string | false | The HTML value for the textarea to set a preset value for the field |
attributes | object | false | HTML attributes (for example, data attributes) to add to the textarea |
label | object<Label> | false | Settings for the label |
width | string | false | Sets the width of the textarea input by number of characters. See input component for details. |
rows | integer | false | Sets the height of the textarea by number of rows. Defaults to “8”. |
charCheckLimit | Object<CharCheckLimit> | false | Settings for the textarea character limit counter |
mutuallyExclusive | MutuallyExclusive (ref) | false | Settings to use the textarea as a mutually exclusive answer |
fieldId | string | false | The HTML id of the field |
fieldClasses | string | false | Classes for the field |
legend | string | false (unless mutuallyExclusive set) | Text for the fieldset legend |
legendClasses | string | false | Classes for the fieldset legend |
description | string | false | The hint text for the mutually exclusive fieldset |
dontWrap | boolean | false | Set to “true” to prevent the textarea from being wrapped in a field component |
legendIsQuestionTitle | boolean | false | Creates an h1 inside the legend. Use when the mutually exclusive textarea is the only fieldset on the page |
error | Error (ref) | false | Settings for validation errors |
Name | Type | Required | Description |
---|---|---|---|
id | string | true | The HTML id of the component |
limit | integer | true | The maximum number of characters allowed in the input |
charCountPlural | string | true | The string displayed when multiple characters can be entered before the limit is reached. Set {x} in the string to be replaced with the number, for example “You have {x} characters remaining”. |
charCountSingular | string | true | The string displayed when one more character can be entered before the limit is reached. Set {x} in the string to be replaced with the number, for example “You have {x} character remaining”. |
Name | Type | Required | Description |
---|---|---|---|
text | string | true | The text content of the label |
for | string | true | Set with the HTML id of the textarea the label is for |
description | string | false | Hint text to help users fill in the input |
classes | string | false | Classes to add to the label |
HTML
<div class="ons-panel ons-panel--error ons-panel--no-title" id="feedback-error">
<span class="ons-panel__assistive-text ons-u-vh">Error: </span>
<div class="ons-panel__body">
<p class="ons-panel__error">
<strong>Enter your feedback</strong>
</p>
<div class="ons-field">
<label class="ons-label ons-label--with-description" for="textarea-error"
aria-describedby="description-hint">Please provide some feedback</label>
<span id="description-hint" class="ons-label__description ons-input--with-description">For example, describe any
difficulties you experienced in the use of this service</span>
<textarea id="textarea-error" class="ons-input ons-input--textarea ons-input--error" name="feedback"
rows="8"></textarea>
</div>
</div>
</div>
If the textarea is empty
Use “Enter [whatever type of text is being asked for]”.
For example, “Enter your feedback” or “Enter a job title”.
Research on this component
This component was last user tested between February and September 2020. The following findings were reported:
- along with the size of the textarea, the character limit helps users know how long their answer should be
- the character counter is often not noticed until the user starts to enter text
- users that look down at a keyboard while they type may not notice the character counter
- users prefer a limit on characters that can be entered as it prevents them entering far more text than is needed
- the change from black to red text when the character limit is reached helps users notice the counter
Help improve this page
Let us know how we could improve this page, or share your user research findings. Discuss the ‘Textarea’ component on GitHub (opens in a new tab)