Cookies on ons.gov.uk

Cookies are small files stored on your device when you visit a website. We use some essential cookies to make this website work.

We would like to set additional cookies to remember your settings and understand how you use the site. This helps us to improve our services.

You have accepted all additional cookies. You have rejected all additional cookies. You can change your cookie preferences at any time.

Skip to main content

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

NameTypeRequiredDescription
idstringtrueThe HTML id of the textarea. Sets the HTML for attribute on the label.
classesstringfalseClasses to add to the textarea
namestringfalseThe HTML name attribute for the textarea
valuestringfalseThe HTML value for the textarea to set a preset value for the field
attributesobjectfalseHTML attributes (for example, data attributes) to add to the textarea
labelobject<Label>falseSettings for the label
widthstringfalseSets the width of the textarea input by number of characters. See input component for details.
rowsintegerfalseSets the height of the textarea by number of rows. Defaults to “8”.
charCheckLimitObject<CharCheckLimit>falseSettings for the textarea character limit counter
mutuallyExclusiveMutuallyExclusive (ref)falseSettings to use the textarea as a mutually exclusive answer
fieldIdstringfalseThe HTML id of the field
fieldClassesstringfalseClasses for the field
legendstringfalse (unless mutuallyExclusive set)Text for the fieldset legend
legendClassesstringfalseClasses for the fieldset legend
descriptionstringfalseThe hint text for the mutually exclusive fieldset
dontWrapbooleanfalseSet to “true” to prevent the textarea from being wrapped in a field component
legendIsQuestionTitlebooleanfalseCreates an h1 inside the legend. Use when the mutually exclusive textarea is the only fieldset on the page
errorError (ref)falseSettings for validation errors
CharCheckLimit
NameTypeRequiredDescription
idstringtrueThe HTML id of the component
limitintegertrueThe maximum number of characters allowed in the input
charCountPluralstringtrueThe 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”.
charCountSingularstringtrueThe 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”.
Label
NameTypeRequiredDescription
textstringtrueThe text content of the label
forstringtrueSet with the HTML id of the textarea the label is for
descriptionstringfalseHint text to help users fill in the input
classesstringfalseClasses to add to the label

HTML

<div class="ons-field">
  <label class="ons-label ons-label--with-description" aria-describedby="description-hint" for="textarea">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
NameTypeRequiredDescription
idstringtrueThe HTML id of the textarea. Sets the HTML for attribute on the label.
classesstringfalseClasses to add to the textarea
namestringfalseThe HTML name attribute for the textarea
valuestringfalseThe HTML value for the textarea to set a preset value for the field
attributesobjectfalseHTML attributes (for example, data attributes) to add to the textarea
labelobject<Label>falseSettings for the label
widthstringfalseSets the width of the textarea input by number of characters. See input component for details.
rowsintegerfalseSets the height of the textarea by number of rows. Defaults to “8”.
charCheckLimitObject<CharCheckLimit>falseSettings for the textarea character limit counter
mutuallyExclusiveMutuallyExclusive (ref)falseSettings to use the textarea as a mutually exclusive answer
fieldIdstringfalseThe HTML id of the field
fieldClassesstringfalseClasses for the field
legendstringfalse (unless mutuallyExclusive set)Text for the fieldset legend
legendClassesstringfalseClasses for the fieldset legend
descriptionstringfalseThe hint text for the mutually exclusive fieldset
dontWrapbooleanfalseSet to “true” to prevent the textarea from being wrapped in a field component
legendIsQuestionTitlebooleanfalseCreates an h1 inside the legend. Use when the mutually exclusive textarea is the only fieldset on the page
errorError (ref)falseSettings for validation errors
CharCheckLimit
NameTypeRequiredDescription
idstringtrueThe HTML id of the component
limitintegertrueThe maximum number of characters allowed in the input
charCountPluralstringtrueThe 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”.
charCountSingularstringtrueThe 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”.
Label
NameTypeRequiredDescription
textstringtrueThe text content of the label
forstringtrueSet with the HTML id of the textarea the label is for
descriptionstringfalseHint text to help users fill in the input
classesstringfalseClasses to add to the label
HTML
<div class="ons-field">
  <label class="ons-label ons-label--with-description" aria-describedby="description-hint"
    for="textarea-char-limit">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-xs"
    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

NameTypeRequiredDescription
exclusiveOptionsArray<Checkbox> or Array<radio>trueConfiguration for the mutually exclusive options
orstringfalseText for the “Or” label that separates the mutually exclusive checkbox from the answer options, defaults to “Or”.
deselectMessagestringtrueThe 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”.
deselectGroupAdjectivestringtrueThe text the aria-live alert will announce when an answer option is cleared or unselected when the mutually exclusive checkbox is selected
deselectCheckboxAdjectivestringtrueThe text the aria-live alert will announce when the mutually exclusive checkbox is unselected when an answer option is selected or entered
errorError (ref)falseConfiguration for validation errors

HTML

<div class="ons-question ons-u-mb-l">
  <div class="ons-question__answer ons-u-mb-m">
    <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">
          <div class="ons-field">
            <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-xs"
              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>
          <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
NameTypeRequiredDescription
idstringtrueThe HTML id of the textarea. Sets the HTML for attribute on the label.
classesstringfalseClasses to add to the textarea
namestringfalseThe HTML name attribute for the textarea
valuestringfalseThe HTML value for the textarea to set a preset value for the field
attributesobjectfalseHTML attributes (for example, data attributes) to add to the textarea
labelobject<Label>falseSettings for the label
widthstringfalseSets the width of the textarea input by number of characters. See input component for details.
rowsintegerfalseSets the height of the textarea by number of rows. Defaults to “8”.
charCheckLimitObject<CharCheckLimit>falseSettings for the textarea character limit counter
mutuallyExclusiveMutuallyExclusive (ref)falseSettings to use the textarea as a mutually exclusive answer
fieldIdstringfalseThe HTML id of the field
fieldClassesstringfalseClasses for the field
legendstringfalse (unless mutuallyExclusive set)Text for the fieldset legend
legendClassesstringfalseClasses for the fieldset legend
descriptionstringfalseThe hint text for the mutually exclusive fieldset
dontWrapbooleanfalseSet to “true” to prevent the textarea from being wrapped in a field component
legendIsQuestionTitlebooleanfalseCreates an h1 inside the legend. Use when the mutually exclusive textarea is the only fieldset on the page
errorError (ref)falseSettings for validation errors
CharCheckLimit
NameTypeRequiredDescription
idstringtrueThe HTML id of the component
limitintegertrueThe maximum number of characters allowed in the input
charCountPluralstringtrueThe 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”.
charCountSingularstringtrueThe 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”.
Label
NameTypeRequiredDescription
textstringtrueThe text content of the label
forstringtrueSet with the HTML id of the textarea the label is for
descriptionstringfalseHint text to help users fill in the input
classesstringfalseClasses 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" aria-describedby="description-hint"
        for="textarea-error">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)