CSS-only experiment

A character limit with no server behind it

Type past 280 characters below and watch the border react — no JavaScript, no request, no round trip to anywhere.

Why this page exists

Everything here lives in one HTML file. The border color, the box growing as you type, the Post button locking past the limit — all of it is plain CSS sitting in a single <style> tag. There's no script, and nothing to call out to.

That matters because "you've typed too much" usually gets treated as JavaScript's job by default. But a slice of that feedback has been built into HTML and CSS for over a decade, through native form validation. This page tests how far that native slice actually goes before a script becomes necessary.

There's no backend anywhere in this file, which also means nothing you type is sent, saved, logged, or read by anyone — including this page itself. Close the tab and it's gone.

Compose a post

No Backend @no-backend

Within the line — this border is exact, not a guess. Past 280 characters — the same signal that just locked the button below.

Up to 10 lines. No hard cap on characters — this border is a signal, not a wall.

Doesn't actually post anywhere. There's nothing to post to.

How the border knows

The textarea above has a minlength of 281 and no maxlength at all. That's deliberate: minlength lets a field report "too short," so setting it to one character past the limit means the field quietly reports too-short for every length from 1 up to 280 — precisely the range that should read as fine. Cross into 281, and that flag clears, so :valid takes over instead. Two CSS rules watch those two states and color the border accordingly, live, on every keystroke, with nothing else involved.

The honest limit of this technique: it's exactly two states, not three. A browser exposes one native "how long is this text" check per field, which draws one line, not two. A true amber "getting close" stage that reacts to an exact character count would need JavaScript reading textarea.value.length on every keystroke. What CSS can still do without one: let the box visibly grow as you type, so you feel yourself approaching the edge before the border ever needs to say so.

That growth is field-sizing: content, capped with max-height: 10lh so it stops at ten lines and scrolls instead of growing forever — the same shape as minlength catching a floor without a hard ceiling. The Post button's lock uses :has() to reach out from the textarea and restyle a completely different sibling, with pointer-events: none actually disabling the click, not just fading it.

minlength
281 — one character past the limit
maxlength
not set, on purpose — nothing stops you from typing on
field-sizing
content, capped at 10 line-heights
:has()
reaches out to lock the Post button past 280

Fig. 1 — the CSS behind the box above