A textarea with maximum characters allowed

Back in 2008 the standard way to limit a textarea was a clipboard-ready script from Dynamic Drive: keypress handlers, document.all sniffing, eval(), the works. It worked, but today you rarely need any of it — HTML has a native attribute for exactly this.

The native way: maxlength

<textarea> (unlike old IE) fully supports the maxlength attribute. The browser silently stops accepting characters past the limit:

<textarea maxlength="200" rows="5" cols="40"></textarea>

The one caveat: maxlength counts JavaScript string units (UTF-16 code units), not user-perceived characters. Emoji and some symbols count as 2. For most inputs this doesn’t matter; for names and social text it can.

Showing a live “characters remaining” counter

The 2008 script existed mostly for the counter, not the limit. That part still needs JavaScript, but it’s a few lines with no browser sniffing:

<label>
  Bio (<span id="remaining">200</span> characters remaining)
</label>
<textarea id="bio" maxlength="200" rows="5" cols="40"></textarea>

<script>
  const bio = document.getElementById('bio');
  const remaining = document.getElementById('remaining');

  function updateCount() {
    remaining.textContent = bio.maxLength - bio.value.length;
  }

  bio.addEventListener('input', updateCount);
  updateCount();
</script>

The input event fires on typing, pasting, drag-and-drop and autofill alike — no keypress/keyup pairs needed. Note the counter doesn’t enforce anything by itself; it just mirrors what maxlength already enforces.

Enforce it on the server too

Client-side limits are a convenience, not a security control — a crafted request skips the browser entirely. Validate the length server-side in whatever stack you use (e.g. strlen() / mb_strlen() in PHP, [MaxLength] in ASP.NET, a schema check in Node). If you need grapheme-accurate counting (emoji, combining characters), use Intl.Segmenter in JS or graphemes-aware functions server-side.

Seventeen years of “progress” here is mostly deletion: the 100-line sniffer script became one attribute plus an optional five-line counter.

Leave a Reply

Your email address will not be published. Required fields are marked *