# HTML textarea, tested in a real form

What a textarea sends when the form is submitted, how maxlength and required really count, and how to keep line breaks. Tested in Chromium.

Author: Formgong
Published: 2026-11-03
Language: en
Canonical: https://formgong.com/en/blog/html-textarea/

A textarea sends its text under its name when the form is submitted, with every line break turned into the two characters CR LF. Its limits are looser than they look. In our Chromium test on 3 November 2026, maxlength="20" held 20 letters but only 10 emoji, and required accepted a box of spaces.

## Why does a message look different when it arrives?

Someone writes you three tidy paragraphs in your contact form, and they arrive as one block of text, or with odd gaps, or cut off half way. Or the form refuses a short message from a real customer and lets through an empty one from a bot. All of that comes down to what a `<textarea>` sends and how its limits count.

To find out, we built a form with several textareas, typed into them in Chromium the way a person does, pressing Enter for new lines, and posted it to a local copy of Formgong's form backend. Then we compared what was in the box, what was in the request and what the backend stored and emailed.

## What does a textarea send?

The browser sends `name=text`, like any other field, so the `name` attribute is the one thing you cannot leave out. The rest of what we saw is in the table.

Textareas typed in Chromium and posted to a local Formgong endpoint, 3 November 2026.
CaseWhat happened
A message with 5 line breaks typed with EnterEach break sent as `%0D%0A` (CR LF), 5 of 5; stored the same way
The same, sent as multipart/form-dataLine breaks sent as CR LF there too
Untouched textarea with a placeholderSent `message=`, an empty value; the placeholder is never sent
Default text that starts on a new line in the HTMLThat first line break was dropped; the rest was sent
Readonly textareaSent
Disabled textarea, or one without a nameNot sent
`maxlength="20"`, 26 letters typed20 kept, 20 sent
`maxlength="20"`, letters and 5 line breaks typed20 characters in the box, 25 on the server
`maxlength="20"`, 12 emoji typed10 kept: each emoji used 2 of the 20
`minlength="10"`, “Hi” typedBlocked: “Please lengthen this text to 10 characters or more”
`minlength="10"`, “Hi” filled in by a scriptSent
`required`, only spaces and line breaksSent
`wrap="hard"` with `cols="20"`, one long line2 line breaks added where the text wrapped
70,000 characters, no maxlengthSent by the browser, refused by Formgong as too large, nothing stored
The line breaks are the part that trips people up. In the page, JavaScript sees each new line as one character. In the request, the browser always sends it as two, a carriage return and a line feed, whichever encoding the form uses. Our article on [how HTML forms work](/en/blog/how-html-forms-work-low-level/) shows the encoded bytes. Your server and your email template then decide whether those breaks survive, which is where most “it all arrived on one line” problems start.

## How do maxlength and minlength count?

`maxlength` counts what JavaScript counts, which is not always what a person counts or what your server receives. Our 20-character box took 20 letters, but only 10 emoji, because each of those emoji is two characters in JavaScript. With five line breaks in it, the box was full at 20 characters and the server received 25, because each break became two characters on the way. If your database column or your server check is exactly as long as `maxlength`, a message with line breaks can be too long for it. Leave some room on the server side.

`minlength` has the opposite gap. It only applies to text a person typed. When we typed “Hi” into a field with `minlength="10"`, Chromium blocked the form and showed its message. When a script put the same “Hi” in the box, the form sent it without a word.

## Does required stop an empty message?

Only a truly empty one. A `required` textarea with nothing in it blocked the form, as expected. One with three spaces, two line breaks and another space counted as filled in, and the form sent it. Bots and impatient people both do this, so trim the text before you decide it is empty. The example below does that before sending, and a field check on the server does it for posts that skip your page. A [honeypot field](/en/blog/honeypot-form-field/) is a cheap first filter for the bots. If your form refuses to send for no clear reason, our guide to an [HTML form not submitting](/en/blog/html-form-not-submitting/) covers the other causes.

## What does wrap="hard" do?

By default a long line wraps on screen but is sent as one line. With `wrap="hard"` and a `cols` width, the browser sends the text with line breaks where it wrapped on screen. Our 62-character line in a 20-column box arrived with 2 extra line breaks. That is almost never what you want for a message, because the breaks depend on the box's width, not on what the person wrote. Leave `wrap` alone unless you are building something like a plain-text email editor.

## How long can a message be?

As long as the browser likes, unless you say otherwise. With no `maxlength`, Chromium happily sent 70,000 characters. Every server has a limit somewhere. Formgong accepts up to 64 KB of text per submission and answered that post with a “too large” error page, storing nothing. Somebody who pasted a long document would lose it, so set a `maxlength` that fits a real message, such as a few thousand characters, and show a counter so people see the limit coming. The example below does both.

```html
<label for="message">Message</label>
<textarea id="message" name="message" rows="6" maxlength="3000" required
          aria-describedby="message-count"></textarea>
<p id="message-count" class="hint">0 / 3000</p>

<script>
  const box = document.getElementById("message");
  const count = document.getElementById("message-count");
  box.addEventListener("input", () => {
    // value.length counts each line break once, the same way maxlength does.
    count.textContent = box.value.length + " / " + box.maxLength;
  });
  box.form.addEventListener("submit", (event) => {
    // required accepts a box of spaces; refuse it here and on the server.
    if (!box.value.trim()) {
      event.preventDefault();
      box.setCustomValidity("Please write a message.");
      box.reportValidity();
      box.setCustomValidity("");
    }
  });
</script>
```

## How do you keep the line breaks when you show the message?

When you put the text back into a web page, HTML collapses line breaks into spaces, so the three paragraphs become one. Set `white-space: pre-wrap` on the element that shows the message and put the text in with `textContent`, never `innerHTML`, so that a message containing `<b>` or a script stays plain text. Static Forms' guide to keeping textarea line breaks, dated 17 October 2026, gives the same advice for previews in the page and rightly points out that if the stored text has already lost its breaks, CSS cannot bring them back.

With Formgong, the email side is done for you. In our test, the notification email kept every line break of that message, because each answer sits in a cell with `white-space: pre-wrap`, and it showed a typed `<b>Two</b>` as those exact characters instead of bold text. The stored copy keeps the original CR LF pairs. Neither competitor guide we read on 3 November 2026 says what its own service does with line breaks. Formspree's textarea tutorial is about the element and its styling, and the Static Forms article is about showing the text in your own page. To build the form itself, the [HTML form generator](/en/tools/html-form-generator/) gives you a contact form with a textarea ready to paste, and the [HTML forms docs](/en/docs/html/) explain each field Formgong reads.

## Did your messages arrive differently?

If your textarea sends something this test did not show, or a message loses its line breaks somewhere between your form and your inbox, write to [support@formgong.com](mailto:support@formgong.com). We will try your case and add it here.

## Frequently asked questions

### How are line breaks sent from a textarea?

As CR LF, two characters, encoded %0D%0A in a normal form post. JavaScript in the page sees each break as one character.

### Does maxlength count line breaks?

Yes, as one character each. The server then receives two per break, so a full box arrives longer than maxlength.

### Is the placeholder text submitted?

No. An untouched textarea sends an empty value under its name; the placeholder is only shown on screen.

### Why does required accept a message of spaces?

The browser only checks that the box is not empty. Trim the text yourself and check it again on the server.

## Sources and documentation

- [Formgong: How do HTML forms work? The HTTP request](https://formgong.com/en/blog/how-html-forms-work-low-level/)
- [Formgong: HTML form not submitting](https://formgong.com/en/blog/html-form-not-submitting/)
- [HTML forms](https://formgong.com/en/docs/html/)

[Get a form key](https://formgong.com/en/#top)
