How to make a textarea
<textarea> is a text field for more than one line: messages, comments, descriptions. rows sets its visible height in lines. Type a few lines and press Send:
Two things differ from <input>: a textarea needs a closing tag, and its starting text goes between the tags instead of in a value attribute. Its name is sent with the text as the value, line breaks included.
Textarea attributes
| Attribute | Does |
|---|---|
name | The key the text is sent under |
rows | Visible height in lines (default 2) |
cols | Visible width in characters (default 20); CSS width is usually better |
placeholder | A hint shown while it is empty |
maxlength, minlength | Length limits in characters |
required | Must not be empty |
readonly | Can be selected and copied, not edited; still sent |
disabled | Cannot be used; not sent |
wrap | soft (default) or hard, see below |
spellcheck | true or false |
Default text goes between the tags
Everything between <textarea> and </textarea> is the starting text, exactly as written: spaces, tabs and line breaks included. Only one line break directly after the opening tag is ignored. That makes indentation a trap:
The second textarea starts with four spaces and ends with a line break and two more, all of which the reader has to delete. Write the default text right against the tags.
HTML inside a textarea is not rendered; <b>hi</b> between the tags shows up as that literal text.
Width, resizing and auto-grow
Browsers let the reader drag the corner to resize a textarea. CSS resize limits that, and width: 100% with box-sizing: border-box makes it fill its container exactly:
The last one resets its height and then sets it to scrollHeight (the height of its content and padding) plus its borders, on every keystroke. Type several lines into it: it never shows a scrollbar. resize: vertical is the friendliest default: long answers get room, and nobody can drag the field wider than the layout.
Chromium browsers can do the auto-grow in CSS alone with field-sizing: content. Browsers that do not support it ignore the line and keep the normal size, so it is safe to add, but keep the script if every reader should get the growing box.
maxlength and a character counter
maxlength stops input at a number of characters. On its own it gives no warning, so the reader only notices when typing stops working. A counter fixes that:
aria-describedby makes screen readers read the counter along with the field, and aria-live="polite" announces changes to it between keystrokes. maxlength is enforced only by the browser, so the server has to check the length too.
Line breaks in the submitted text
The reader's line breaks are sent with the text. In the submitted data each one becomes a carriage return and line feed pair (%0D%0A in a URL-encoded form), which is what most servers expect. To show the text on a page later with its line breaks, either convert them to <br> on output or style the element with white-space: pre-line.
wrap="hard" (which needs cols) goes further: it also inserts line breaks where the text wrapped visually, so the server receives lines no longer than cols characters. The default, wrap="soft", sends only the breaks the reader typed.
Styling a textarea
Chrome and Firefox give textareas a monospace font at about 13px, which is why a textarea often looks out of place. font: inherit fixes it. Keep a visible focus style if you change the border:
Placeholder text should reach a readable contrast; the light gray many designs use is hard to read. And, like on every field, the placeholder is not a label: it disappears as soon as the reader types. Labels are covered in HTML label.
Common mistakes
<textarea value="...">. There is novalueattribute; put the text between the tags.- Indenting the default text along with the HTML. The spaces become part of the value.
- A self-closing
<textarea />. It is not a void element; without</textarea>, the rest of the page is swallowed into it as text. - No
font: inherit, so the field uses a small monospace font. resize: nonewith a small fixed height. Long answers end up in a tiny scrolling box.- Relying on
maxlengthalone. Validate the length on the server as well.
Frequently Asked Questions
How do you create a textarea in HTML?
Write <textarea name="message" rows="4"></textarea> inside a form, with a <label>. Unlike <input>, it has a closing tag, and anything between the tags is the starting text.
How do I set the default value of a textarea?
Put the text between the tags: <textarea name="bio">Hello</textarea>. A textarea has no value attribute in HTML. In JavaScript, read and set textarea.value.
How do I stop a textarea from being resized?
Set resize: none in CSS. resize: vertical is usually friendlier: the reader can still make it taller for long text, but cannot break your layout by dragging it wider.
How do I limit the number of characters in a textarea?
Add maxlength="280". The browser stops accepting input at that length. Show a counter next to it, updated on the input event, so the reader knows how much room is left, and check the length on the server too.
Why does my textarea use a different font?
Chrome and Firefox give textareas a monospace font at about 13px by default. Add font: inherit to make it match the rest of the page.