Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

The HTML <textarea> Element

Learn the HTML <textarea> element from first principles through multiline text editing, attributes, form behavior, accessibility, validation hooks, and its advanced value model.

Levels: Beginner, Intermediate, Advanced ~45 min read

Basic

The <textarea> element creates a multiline plain-text editing control. Unlike <input>, it has opening and closing tags, and the text between those tags supplies its initial value. It is designed for comments, messages, descriptions, notes, code-like text, and other values that naturally span multiple lines.

What the <textarea> element represents

A <textarea> represents a native multiline text editor. It is flow content, phrasing content, interactive content, labelable, listed, submittable, and resettable. Its permitted content is text, not arbitrary HTML elements, and neither its start tag nor its end tag may be omitted.

html
<label for="message">Message</label>
<textarea id="message" name="message" rows="6" cols="40"></textarea>

Quick check

Complete the form with the element for a multi-line text entry control.

<label for="message">Message</label>
< id="message" name="message"></textarea>

The browser owns the editing behavior. Your HTML declares the meaning and constraints of the control; CSS controls presentation, and JavaScript can read or change the live value and selection.

It is not a void element

Unlike <input>, <textarea> requires both a start tag and an end tag. The element cannot contain child elements, but its text content can establish its default value.

html
<textarea name="notes">Start with this text.</textarea>

Putting HTML markup inside a <textarea> does not create child elements. The characters are treated as text. This makes <textarea> appropriate for plain-text input, not for rich-text editing.

The initial value comes from the text content

In HTML, the initial value is written between the opening and closing tags. There is no value attribute that serves the same purpose as the value attribute on <input>.

html
<textarea name="message">Hello, world!</textarea>

At the DOM level, defaultValue represents the initial/default value, while value represents the current live value. This distinction becomes important after the user edits the control or script changes its value.

Interactive Runnable example
Edit

Ready to run.

Give the control an identity and a submitted name

Use id when another element needs to reference the control, especially a label. Use name when the control should contribute a named value during form submission. These attributes solve different problems and are often both needed.

html
<label for="feedback">Feedback</label>
<textarea id="feedback" name="feedback"></textarea>

A control without a name can still be edited and accessed by JavaScript, but it does not contribute a successful form value under a normal form submission model. The cross-element submission lesson will cover that behavior in depth.

Labels are part of the control design

A textarea should normally have an accessible label. The explicit label pattern uses a label whose for value matches the textarea id. A wrapping <label> is another valid association pattern.

html
<label for="bio">Short biography</label>
<textarea id="bio" name="bio"></textarea>

Placeholder text is not a substitute for a label. A placeholder is transient instructional text; a label identifies what the field is for.

Form ownership

A textarea can belong to a form by being a descendant of that form, or it can explicitly name its form owner with the form attribute. The latter is useful when document structure and form ownership need to be separated.

html
<form id="profile-form">
  <button type="submit">Save</button>
</form>

<label for="bio">Biography</label>
<textarea id="bio" name="bio" form="profile-form"></textarea>

The form attribute references the id of a form in the same document. It does not mean “submit to this form URL”; it establishes which form owns the control.

Intermediate

Textarea attributes control different aspects of the editing experience.

Attribute

Controls

What it does not define

rows

Initial visible height

The submitted value length

cols

Initial visible width

The exact CSS width

placeholder

Hint shown when empty

The control value

maxlength

Maximum allowed text length for validation/user input

A server-side security limit

readonly

Whether the user can edit the value

Whether the value is disabled

Sizing: rows and cols

rows and cols describe the textarea’s visible dimensions in terms of lines and average character widths. They are HTML sizing hints for the native control, not a promise about every final pixel dimension.

html
<textarea rows="8" cols="60" name="essay"></textarea>

The HTML Standard defines positive integer values for rows and cols. When omitted, browsers use their defaults. CSS is normally the better layer for responsive layout, while rows and cols provide useful intrinsic sizing information.

placeholder: a hint, not content

placeholder supplies a short hint shown when the control has no value. It is useful for examples or brief instructions, but it should not carry essential information that disappears as soon as the user types.

html
<label for="comment">Comment</label>
<textarea id="comment" name="comment" placeholder="Share your experience..."></textarea>

If users need a longer explanation, provide visible instructional text or other appropriate help rather than turning the placeholder into a paragraph.

required and the difference between empty and invalid

required says the user must provide a value before a form can be successfully submitted under native constraint validation. A textarea can be empty when required is absent; required changes that validation condition.

html
<label for="reason">Reason</label>
<textarea id="reason" name="reason" required></textarea>

A minlength constraint by itself does not make an empty value invalid in the same way required does. If a field must contain something, use required; if a non-empty value also needs a minimum length, the two constraints can work together.

minlength and maxlength

minlength defines a minimum value length and maxlength defines a maximum value length. The relevant length is measured in UTF-16 code units for the HTML form-control model. These constraints participate in native constraint validation.

html
<textarea name="summary" minlength="20" maxlength="500"></textarea>

maxlength can limit what the user can enter, while minlength does not force the user to keep typing until the minimum is reached. A value can therefore be edited into an invalid state until the constraint is satisfied.

readonly versus disabled

readonly prevents the user from modifying the value while still allowing the control to remain part of the form-control interaction model. disabled makes the control non-interactive and excludes it from normal form submission.

html
<textarea name="generated" readonly>Generated text</textarea>
<textarea name="unavailable" disabled>Temporarily unavailable</textarea>

This distinction matters: readonly preserves a value that can still be submitted, whereas disabled removes the control from normal user interaction and successful form submission.

autocomplete and related editing hints

autocomplete can provide an autofill hint and may inherit behavior from the form owner when omitted. Other global or form-related attributes such as autocapitalize, autocorrect, autofocus, spellcheck, and inputmode can affect the editing experience where supported and applicable.

These attributes are hints about user-agent behavior, not guarantees that every browser, operating system, or input method will present identical UI.

dirname and directionality

dirname can request that the text direction of the control’s value be submitted alongside the value. This is useful when users may enter text in different writing directions and the server needs that directionality information.

html
<label for="comment">Comment</label>
<textarea id="comment" name="comment" dirname="comment.dir"></textarea>

The global dir attribute controls document and element directionality for rendering. dirname is different: it adds directionality information to form submission.

wrap: display wrapping versus submitted value

wrap controls how line wrapping is handled for the value used in form submission. soft is the default: visual wrapping does not add corresponding line breaks to the submitted value. hard can insert line breaks based on the control width, and requires cols. off behaves like soft but changes the presentation so long lines are not wrapped.

html
<textarea name="message" cols="50" wrap="hard"></textarea>

Textarea content is plain text

The textarea content model is text. HTML elements written inside the control are not interpreted as descendants. This is one reason textarea is fundamentally different from a rich-text editor built with contenteditable or a specialized editor library.

html
<textarea>&lt;strong&gt;Not bold&lt;/strong&gt;</textarea>

When you need rich formatting, do not try to turn textarea into an HTML renderer. Choose an appropriate editing model and establish a safe serialization and rendering boundary.

Constraint validation belongs to the element, but not all validation belongs here

A textarea participates in native constraint validation through conditions such as required, minlength, and maxlength. The browser exposes validity state and pseudo-classes such as :valid and :invalid.

html
<textarea name="comment" required minlength="10" maxlength="500"></textarea>

This lesson explains the textarea-specific validation hooks. A later Form Validation lesson will own cross-element validation strategy, custom validity, validation UI, submission blocking, and broader form-validation architecture.

Advanced

The live value and the default value are different states

HTML form controls distinguish a current value from a default value. A textarea starts with a default value derived from its text content. Before the control becomes dirty, its current value follows that default. User editing or script assignment can make the value dirty, after which changing the default does not simply overwrite the current value.

html
const field = document.querySelector("textarea");
console.log(field.defaultValue);
console.log(field.value);

This is why reading textContent and reading value are not interchangeable. textContent reflects the element’s DOM text; value reflects the control’s current API value.

Quick check

A user edits this textarea from its initial text. Which statement correctly describes the DOM properties?

<textarea id="note">Start here</textarea>

value versus defaultValue versus textContent

defaultValue represents the control’s default value and can be read or set through the HTMLTextAreaElement interface. value represents the current value. textContent addresses the DOM text nodes. These can diverge after user interaction or script changes.

html
const field = document.querySelector("textarea");

console.log(field.textContent);
console.log(field.defaultValue);
console.log(field.value);

For application behavior, use value when you mean “what is in the control now.” Use defaultValue when you mean “what should reset restore.” Treat raw DOM text as a different layer.

Reset restores the default value

Because textarea is resettable, resetting its form restores the control according to its default value. If script or the user has changed the current value, reset can therefore produce a visible change even though the HTML source has not changed.

html
<form>
  <textarea name="notes">Original notes</textarea>
  <button type="reset">Reset</button>
</form>

This is another reason to distinguish initial/default content from the current editing state.

The HTMLTextAreaElement interface

JavaScript exposes textarea controls through HTMLTextAreaElement. In addition to inherited HTMLElement behavior, the interface exposes form-control properties such as value, defaultValue, validity, validationMessage, rows, cols, maxLength, minLength, readOnly, required, disabled, form, and selection-related APIs.

js
const field = document.querySelector("textarea");

field.value = "Updated by script";
console.log(field.validity.valid);
console.log(field.selectionStart, field.selectionEnd);

The DOM interface is an API over the native control model. It does not turn textarea into a generic text container.

input and change events

A textarea fires input as its value is edited and change when the value is committed according to the browser’s form-control event model. For live character-by-character reactions, input is usually the relevant event.

js
const field = document.querySelector("textarea");

field.addEventListener("input", () => {
  console.log(field.value);
});

Event timing is part of the interaction model, so avoid assuming that change fires on every keystroke.

Selection APIs

Textarea supports selectionStart, selectionEnd, selectionDirection, select(), setSelectionRange(), and setRangeText(). These operate on the textarea’s API value and let scripts inspect or manipulate the user’s text selection.

js
const field = document.querySelector("textarea");
field.focus();
field.setSelectionRange(0, 5);

Selection offsets are measured in code units of the relevant value. This matters when handling Unicode text programmatically: visible characters and UTF-16 code units are not always one-to-one.

Newlines and value normalization

Textarea has special newline processing because it is a multiline text control. The HTML form-control algorithms normalize line endings for its API value and selection operations. Do not assume that the exact byte or code-point sequence in source markup is identical to every API representation.

js
const field = document.querySelector("textarea");
field.value = "A\r\nB";
console.log(field.value);

When implementing editors, serialization, or character counts, use the API whose semantics match the task instead of manually treating textarea as an arbitrary text node.

maxlength and programmatic values

The user-facing enforcement and the DOM APIs are related but not identical concepts. Native constraints describe what values are valid and how user interaction is constrained; scripts can set properties and should still respect the validity model when application logic depends on constraints.

If your application needs a hard server-side limit, enforce it on the server too. HTML constraints improve the user experience but are not a security boundary.

Browser and platform UI is not the HTML contract

Browsers and operating systems can render textareas differently: default dimensions, resize affordances, spell-check UI, virtual keyboards, scrolling, focus rings, and other editing details can vary. The HTML semantics and control behavior remain the stable contract; pixel-identical native UI is not.

CSS belongs to presentation

Use CSS for responsive dimensions, typography, spacing, borders, resize behavior, and visual states. HTML attributes such as rows and cols still communicate useful native-control sizing information, but they should not become a substitute for a complete layout system.

css
textarea {
  width: 100%;
  min-height: 10rem;
  resize: vertical;
}

Be careful with CSS assumptions around baselines and native control rendering. Test the actual interaction at the browser and platform combinations that matter to your product.

Accessibility: preserve the native textbox semantics

Textarea has an implicit textbox role. Authors should normally keep the native semantics rather than replacing them with a generic role. Provide a clear accessible name through a label and keep instructions, errors, and constraints understandable in the surrounding content.

html
<label for="support-message">What can we help with?</label>
<textarea id="support-message" name="message" required aria-describedby="message-help"></textarea>
<p id="message-help">Include the steps that reproduce the problem.</p>

Use ARIA to supplement native semantics when necessary, not to recreate the behavior of a native textarea from scratch.

Readonly, disabled, and hidden are not interchangeable

readonly means the current value cannot be edited by the user; disabled means the control is unavailable and excluded from normal form submission; CSS visibility or visually hiding an element is a separate presentation decision. Choose the state that matches the actual product semantics.

Security boundary: textarea does not sanitize data

Textarea accepts plain text, but your application may later place that text into HTML, SQL, shell commands, logs, templates, or other interpreters. The textarea itself does not sanitize those downstream uses. Encode, validate, parameterize, or otherwise process the value according to the context in which it will later be used.

Common authoring mistakes

  • Using a value attribute instead of text content for the initial value.

  • Using placeholder as the only label.

  • Assuming minlength prevents users from entering fewer characters.

  • Confusing readonly with disabled and accidentally dropping a value from submission.

  • Treating rows and cols as a complete responsive layout system.

  • Assuming visual line wrapping means newline characters exist in the value.

  • Reading textContent when application logic actually needs the current value.

  • Building rich-text semantics into textarea instead of choosing a suitable rich-text editing architecture.

  • Trusting client-side constraints as a server-side security boundary.

  • Replacing native textarea semantics with unnecessary ARIA or custom keyboard behavior.

A practical textarea checklist

  • Give the control a clear label.

  • Use name when its value belongs in form submission.

  • Use id when you need explicit labeling or other references.

  • Choose rows and cols as useful native sizing hints, then use CSS for responsive presentation.

  • Use placeholder only for short, non-essential hints.

  • Use required, minlength, and maxlength when native constraints match the requirement.

  • Choose readonly or disabled deliberately.

  • Use form when the control must belong to a non-ancestor form.

  • Use dirname when submitted text direction matters.

  • Use value in JavaScript for the current value and defaultValue for the reset/default state.

  • Use input for live editing and the appropriate selection APIs for text manipulation.

  • Remember that cross-element validation and submission architecture belong to the later dedicated lessons.

Practice: design a feedback field

Create a feedback form with a labelled textarea that starts with a short default message, is at least 20 characters when filled, is capped at 500 characters, belongs to the form, and provides a concise placeholder. Then add JavaScript that reports the live character count from value on input without changing the user’s text.

html
<form id="feedback-form">
  <label for="feedback">Feedback</label>
  <textarea
    id="feedback"
    name="feedback"
    rows="6"
    cols="50"
    minlength="20"
    maxlength="500"
    placeholder="Tell us what you think..."
    required
  >My initial feedback.</textarea>
  <p id="count">0 characters</p>
  <button type="submit">Send</button>
</form>
js
const feedback = document.querySelector("#feedback");
const count = document.querySelector("#count");

function updateCount() {
  count.textContent = `${feedback.value.length} characters`;
}

feedback.addEventListener("input", updateCount);
updateCount();

Where this lesson stops

This lesson owns the <textarea> element: its semantics, content model, attributes, value model, DOM interface, editing events, selection APIs, accessibility, and element-specific constraints. The upcoming Form Validation lesson will own cross-element validation strategy, custom validity, validation UI, and submission blocking. The Form Submission lesson will own the broader mechanics of successful controls, encoding, methods, and server-facing submission behavior.

Was this page helpful?

Mark this learning resource complete to track your learning progress.