HTML Textarea
The <textarea> element creates a multi-line, resizable text input box inside an HTML form. Unlike a single-line <input type="text">, a textarea lets users type paragraphs of content — comments, messages, feedback, code snippets, or any free-form text that spans more than one line. It’s one of the most commonly used form controls on the web, powering everything from contact forms to comment sections.
Overview / How it works
A textarea is a form control, meaning it only does something useful when placed inside a <form> (or associated with one via the form attribute). When the browser parses a <textarea> tag, it creates a special DOM node that behaves differently from most other elements: everything between the opening <textarea> tag and the closing </textarea> tag is treated as the control’s initial text content, not as child HTML elements. This means the parser switches into a special “raw text” parsing mode for the contents of a textarea — angle brackets and ampersands typed inside it are shown literally as text rather than being interpreted as markup (though you should still use character references like & for safety and clarity).
Semantically, a textarea communicates to assistive technology and to the browser’s rendering engine that this is an editable, multi-line plain-text region. Visually, browsers render it as a rectangular box with a border, typically with a small resize handle in the bottom-right corner that lets the user drag to make the box bigger or smaller (this default resize behavior comes from the browser’s built-in style sheet, and can be turned off with CSS in a real project, though that belongs to the CSS course, not this one). Internally, the textarea’s current text is exposed through the DOM as its value property in JavaScript, but in raw HTML the *initial* value is simply the text you place between the tags.
Textareas participate in form submission just like text inputs: when the form is submitted, the textarea’s name attribute pairs with its current text content and is sent to the server. Newlines the user types are preserved and submitted using the CRLF (\r\n) line-ending convention as defined by the HTML specification, regardless of the operating system.
Syntax
<label for="message">Message</label>
<textarea id="message" name="message" rows="4" cols="40">
Default text goes here.
</textarea>
Key attributes of <textarea>:
| Attribute | Purpose |
|---|---|
name |
The key used when the form data is submitted; required for the value to be sent at all. |
id |
Used to associate the textarea with a <label> via the label’s for attribute. |
rows |
The visible height in number of text lines (a rendering hint, not a hard character limit). |
cols |
The visible width in average character widths. |
placeholder |
Faint hint text shown when the textarea is empty; disappears once the user types. Not a substitute for a label. |
maxlength |
The maximum number of characters the user is allowed to enter. |
minlength |
The minimum number of characters required for the value to be considered valid. |
required |
Boolean attribute; the form cannot be submitted until the textarea has a value. |
readonly |
The text is visible and can be selected/copied but cannot be edited; the value is still submitted. |
disabled |
The control is grayed out, cannot be focused or edited, and its value is NOT submitted with the form. |
wrap |
Controls how text wrapping affects submitted line breaks: soft (default, wraps visually but submits as one long line per paragraph) or hard (inserts actual line breaks at the wrap points; requires cols to be set). |
autofocus |
Automatically focuses this control when the page loads. |
form |
Associates the textarea with a form elsewhere in the document by that form’s id, useful when the textarea isn’t nested inside the <form> tag. |
Examples
Example 1: A basic comment box
<form action="/submit-comment" method="post">
<label for="comment">Your comment</label><br>
<textarea id="comment" name="comment" rows="5" cols="40"></textarea><br>
<button type="submit">Post Comment</button>
</form>
Result: The browser renders a label reading “Your comment”, followed by an empty, resizable text box roughly 5 lines tall and 40 characters wide, and a “Post Comment” button beneath it. Clicking inside the box lets the user type multiple lines of free-form text.
This is the minimal, correct pattern: the textarea is empty (no text between the tags), it has a name so its value is submitted, and a <label> is properly linked via matching for/id values so screen readers and click-to-focus both work.
Example 2: Pre-filled text, placeholder, and validation constraints
<form action="/feedback" method="post">
<label for="feedback">Feedback (10-500 characters)</label><br>
<textarea
id="feedback"
name="feedback"
rows="6"
cols="50"
minlength="10"
maxlength="500"
placeholder="Tell us what you think..."
required
>We loved using your product because</textarea><br>
<button type="submit">Send Feedback</button>
</form>
Result: The textarea appears already containing the sentence “We loved using your product because” as editable, pre-filled text (the placeholder is not shown, since placeholders only appear in empty fields). If the user deletes all the text and tries to submit, the browser blocks submission and shows a validation message because of required and minlength. Typing beyond 500 characters is prevented by maxlength.
Notice that the initial value comes from the literal text between the opening and closing tags — there is no value attribute on <textarea> (unlike <input>). The minlength/maxlength/required attributes trigger the browser’s built-in HTML5 form validation without any JavaScript.
Example 3: Read-only, disabled, and hard-wrapped variants
<form action="/submit" method="post">
<label for="terms">Terms (read-only)</label><br>
<textarea id="terms" name="terms" rows="4" cols="50" readonly>
By submitting this form you agree to our sample terms of service.
</textarea><br>
<label for="notes">Internal notes (disabled)</label><br>
<textarea id="notes" name="notes" rows="3" cols="50" disabled>Not editable and not submitted</textarea><br>
<label for="poem">Poem (hard-wrapped)</label><br>
<textarea id="poem" name="poem" rows="4" cols="20" wrap="hard">Roses are red, violets are blue.</textarea>
</form>
Result: Three boxes appear stacked. The first (“terms”) shows its sentence but the text cannot be edited, though it is still sent to the server on submit and the user can still select and copy it. The second (“notes”) appears visually grayed out, cannot receive focus, and its value is silently omitted from the submitted form data. The third (“poem”) visually wraps its long line inside the narrow 20-column box, and because wrap="hard" is set, the actual submitted value will contain real newline characters at each point the text wrapped on screen, instead of one continuous line.
How it works step by step
- The HTML parser reaches
<textarea>and switches into a special text-parsing mode, so everything until the matching</textarea>is captured as raw character data, not parsed as nested tags. - The browser trims a single leading newline immediately after the opening tag, if present, per the HTML specification — this is why authors often start the content on its own line without worrying about an extra blank line appearing.
- The DOM node created is an
HTMLTextAreaElement, exposing that captured text as itsvalueproperty, along with the parsed attributes likerows,cols, andmaxlength. - The rendering engine paints a bordered, scrollable box sized according to
rowsandcols(or CSS, if applied), with a native resize handle by default. - As the user types, the browser continuously updates the internal value and, if constraints like
requiredormaxlengthare set, tracks the control’s validity state. - On form submission, unless the control is
disabled, itsnameand current value are added to the submitted form data, with line breaks normalized to CRLF.
Common Mistakes
Mistake 1: Using a value attribute instead of inner text
<textarea name="bio" value="Write something about yourself"></textarea>
This is wrong because <textarea> does not support a value attribute at all — browsers ignore it, so the textarea renders empty instead of showing the intended default text. The initial value must be placed as plain text between the opening and closing tags:
<textarea name="bio">Write something about yourself</textarea>
Mistake 2: Treating textarea as a self-closing / void element
<textarea name="bio" />
This is wrong because <textarea> is not a void element like <br> or <img> — it always requires an explicit closing tag, even when you want it to start empty. Writing it as self-closing can cause the parser to treat all the following markup on the page as if it were inside the textarea, silently breaking the rest of the document. The correct form always has a real closing tag:
<textarea name="bio"></textarea>
Mistake 3: No associated label
Bio: <textarea name="bio" rows="4" cols="40"></textarea>
This is wrong because plain text sitting next to a textarea is not programmatically connected to it — screen reader users won’t hear “Bio” announced when they focus the field, and clicking the word “Bio” won’t focus the box. Use a real <label> tied to the textarea’s id:
<label for="bio">Bio</label>
<textarea id="bio" name="bio" rows="4" cols="40"></textarea>
Best Practices
- Always pair a textarea with a properly associated
<label>using matchingforandidattributes — never rely on placeholder text alone as a label substitute. - Set an initial value by placing plain text between the tags, never with a
valueattribute (textareas don’t have one). - Use
rowsandcolsto give a sensible default size, but remember users can typically resize the box themselves — don’t assume a fixed size. - Use
maxlengthandminlengthfor lightweight client-side validation, but always re-validate on the server, since client-side constraints can be bypassed. - Reach for
readonlywhen a value should be visible and submittable but not editable, anddisabledwhen it should be excluded from submission entirely — the two are not interchangeable. - Only use
wrap="hard"when you specifically need submitted line breaks to match the visual wrapping (e.g., preformatted addresses); otherwise the defaultsoftwrap is usually what you want. - Escape literal
<,>, and&characters inside default textarea content using entities to avoid confusing the parser or other tools that process the HTML.
Practice Exercises
- Build a simple “Contact Us” form with a
<label>and a<textarea>namedmessage, requiring at least 20 characters and no more than 300, with a submit button. - Create a form with two textareas: one
readonlyshowing a fixed set of terms, and one normal editable textarea where the user must type “I agree” before the form becomes valid (hint: think about howrequiredworks, or consider what a pattern-based check on an input might add if paired with a checkbox instead). - Add a textarea with
wrap="hard"and a narrowcolsvalue, prefill it with a long sentence, and predict where the submitted line breaks will fall based on the visible wrapping.
Summary
- The
<textarea>element provides a resizable, multi-line text input inside forms. - Its initial value is the literal text placed between the opening and closing tags — there is no
valueattribute. rowsandcolsset the visible size;maxlength,minlength, andrequiredadd built-in validation.readonlykeeps the value submittable but uneditable;disabledexcludes it from submission entirely.wrap="hard"vs. the defaultsoftcontrols whether visual line wraps become real newlines in the submitted data.- Always associate a textarea with a proper
<label>for accessibility, and never treat it as a self-closing tag.
