LEARNING OBJECTIVES ⌵
- Understand the distinct behavioral models of
minlength(validation blocking) vsmaxlength(input truncation). - Map length constraints to the
validity.tooShortandvalidity.tooLongConstraint Validation API flags. - Recognize why an empty input field satisfies
minlengthunless explicitly combined withrequired. - Deconstruct Unicode string counting: UTF-16 code units vs code points vs extended grapheme clusters (emojis and ZWJ sequences).
- Build a robust, accessible real-time character counter with
aria-livestate announcements.
📖 The Mental Model & Story (Intuitive Foundation)
Imagine writing a micro-essay for a competitive scholarship:
+-----------------------------------------------------------------------------+
| THE SCHOLARSHIP ESSAY ANALOGY |
+-----------------------------------------------------------------------------+
| |
| Rules: Minimum 50 words (minlength), Maximum 280 words (maxlength) |
| |
| [Student Writes 20 words] ──► Allowed to type freely. |
| Tries to submit: Professor rejects it! |
| ⚠️ "Too short! (tooShort = true)" |
| |
| [Student Reaches 280 words] ─► The submission portal physically locks |
| the keyboard. Further typing is blocked! |
| 🛑 Native input truncation |
| |
| [The Emoji Surprise 👨👩👧👦] ──► 1 visible family icon on screen, |
| but 11 UTF-16 code units under the hood! |
| |
+-----------------------------------------------------------------------------+
maxlengthis a Physical Barrier: As you type, once you hit the maximum character count, the browser physically stops accepting further keyboard input and truncates pasted content.minlengthis an Evaluation Standard: The browser lets you type freely below the threshold. However, if you attempt to submit a non-empty string that has fewer characters thanminlength, the browser halts submission and flags the input withtooShort = true.- The Unicode Reality: The browser does not count characters the way human eyes see them (glyphs). It counts UTF-16 code units. A single colorful emoji like
👨👩👧👦looks like 1 character to a human, but consumes 11 UTF-16 code units in the browser's engine!
Technical Deep Dive & Specifications
2.1 Enforcement Differences: minlength vs maxlength
According to the WHATWG HTML Standard (§ 4.10.5.3.5 & § 4.10.5.3.6):
| Attribute | User Typing Behavior | Paste Behavior | Submit Behavior | API Validity Flag |
|---|---|---|---|---|
minlength="N" |
Free typing allowed below $N$ | Paste allowed below $N$ | Blocks submit if $0 < \text{len} < N$ | validity.tooShort |
maxlength="N" |
Keyboard typing blocked at $N$ | Paste truncated at $N$ | Blocks submit if $\text{len} > N$ | validity.tooLong |
+----------------------------------------------------------------------------------------------------+
| MINLENGTH / MAXLENGTH LIFECYCLE |
+----------------------------------------------------------------------------------------------------+
In HTML: <input type="text" minlength="5" maxlength="10">
1. Initial State: value = ""
• valueMissing = false (unless 'required' is present)
• tooShort = false (Empty strings are EXEMPT from minlength!)
2. User types: "abc" (length = 3)
• tooShort = true (3 < 5)
• Form submission is BLOCKED.
3. User types: "abcdef" (length = 6)
• tooShort = false, tooLong = false
• Form submission is ALLOWED.
4. User types: "abcdefghij" (length = 10)
• Keyboard stops accepting keypresses (max reached).
5. Programmatic Script sets: input.value = "abcdefghijklmnop" (length = 16)
• tooLong = true (16 > 10)
• Form submission is BLOCKED.
Important Rule:
minlengthonly applies when the input is not empty. If a user leaves aminlength="5"optional field blank, it will submit without error. To require at least 5 characters and disallow empty submission, combinerequiredandminlength="5".
2.2 The Unicode UTF-16 Code Unit Reality
The WHATWG specification explicitly mandates that length constraints are calculated using the string's UTF-16 code units (equivalent to JavaScript string.length), not human-perceived characters (Extended Grapheme Clusters).
+----------------------------------------------------------------------------------------------------+
| HOW THE BROWSER COUNTS CHARACTERS |
+----------------------------------------------------------------------------------------------------+
Character / Glyph Unicode Code Points UTF-16 Code Units (HTML length)
──────────────────────────────────────────────────────────────────────────────────────────────────
'A' U+0041 1 code unit (length = 1)
'é' (precomposed) U+00E9 1 code unit (length = 1)
'é' (decomposed e + ´) U+0065 + U+0301 2 code units (length = 2)
'😀' (Grinning Face) U+1F600 (Surrogate Pair) 2 code units (length = 2)
'👨👩👧👦' (Family Emoji) U+1F468 + U+200D + U+1F469 + 11 code units (length = 11)
U+200D + U+1F467 + U+200D + U+1F466
If your application has <input maxlength="10">, a user attempting to paste the family emoji 👨👩👧👦 (11 code units) will have the emoji completely rejected or broken in half because it exceeds the 10 code unit limit!
Modern JavaScript Solution: Intl.Segmenter
To count visible characters accurately for user interfaces:
// Grapheme-aware counting (Matches human eyes)
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
const countGraphemes = (str) => [...segmenter.segment(str)].length;
console.log(countGraphemes('👨👩👧👦')); // Returns 1 (Correct for humans!)
console.log('👨👩👧👦'.length); // Returns 11 (HTML native UTF-16 count)
💻 Interactive Code Playground
Starter Code
The following microblog post publisher demonstrates minlength, maxlength, real-time visual progress, Unicode breakdown, and live validity flag inspection.
Line-by-Line Code Breakdown
- Lines 82-90 (
minlength="5" maxlength="40" required): Enforces that the title must contain at least 5 characters and truncates typing at 40 characters. - Lines 99-107 (
minlength="20" maxlength="140" required): Sets textarea boundaries. If a user types 10 characters and clicks submit, the browser prevents submission withvalidity.tooShort = true. - Line 108 (
aria-live="polite"): Ensures that as the character count updates, screen reader users receive periodic, non-intrusive character count announcements. - Lines 132-134 (
Intl.Segmenter): Uses the modern internationalization API to split strings by user-perceived grapheme clusters, exposing the difference between native UTF-16 code units and visible characters. - Lines 147-156 (
bValidity.tooShort,bValidity.tooLong): Real-time inspection of length validity flags.
Expected Browser Render Output
+---------------------------------------------------------------+
| Microblog Broadcast |
| Enforcing minimum and maximum string boundaries. |
| |
| Broadcast Title (5 – 40 Chars) * |
| [ Release v2.4 Announcement ] |
| Min: 5 characters 24 / 40 UTF-16 (24 glyphs) |
| |
| Broadcast Message (20 – 140 Chars) * |
| [ We are thrilled to launch our new constraint validation... ] |
| Min: 20 characters 58 / 140 UTF-16 (58 glyphs) |
| |
| [ Publish Broadcast ] |
| |
| [BODY VALIDITY STATE] |
| • Native UTF-16 Length: 58 / 140 |
| • Human Grapheme Count: 58 |
| • validity.tooShort: false |
| • validity.tooLong: false |
| • validity.valueMissing: false |
| • validity.valid: true |
+---------------------------------------------------------------+🏋️ Hands-On Exercise
🎯 The Challenge: Developer Bio & Security PIN Editor
Scenario: You are building an account security settings panel.
- Security PIN: Must be exactly 6 characters (
minlength="6" maxlength="6" inputmode="numeric" required). - Developer Biography: Must be between 30 and 250 characters (
minlength="30" maxlength="250"). - Character Counter: Implement a real-time counter displaying remaining characters for the biography (
"X characters remaining").
Instructions:
- Write the HTML form with the security PIN and bio textarea controls.
- Apply
minlength,maxlength, andrequiredattributes. - Write JavaScript to calculate and display remaining characters as the user types into the textarea.
- If remaining characters drop below 20, turn the counter text amber/warning.
🏁 Starter Code Sandbox
⚠️ Common Pitfalls
- Assuming
minlengthBlocks Empty Fields: If a field hasminlength="10"but is NOT markedrequired, submitting an empty string""will succeed because empty values are exempt fromminlength. Always includerequiredif the input cannot be omitted. - Relying on
maxlengthfor Backend Database Protection: An attacker usingcurlor modifying the DOM via DevTools can post a 50,000-character payload regardless of yourmaxlengthattribute. Always validate string lengths on the server before database persistence. - The Emoji Cutoff Bug: Emojis using Unicode Surrogate Pairs consume 2 UTF-16 code units. If
maxlength="5"and the user types 4 ASCII letters ("test") and pastes an emoji ("😀"), the emoji will be rejected or truncated into an invalid surrogate fragment.
💡 Pro Tips
- Accurate Counting with
Intl.Segmenter: For user-facing character counters, always count withIntl.Segmenterso compound emojis, flags, and accented characters are counted as single glyphs. - Accessibility with
aria-live="polite": When rendering dynamic character countdowns, mark the counter container witharia-live="polite"so screen readers announce remaining character milestones to visually impaired users without interrupting ongoing speech.
📌 Key Takeaways
maxlengthTruncates: Physically prevents users from typing or pasting beyond the limit.minlengthBlocks Submit: Allows typing below the limit, but setsvalidity.tooShort = trueduring validation attempts.- Empty Exemption: An empty string does not trigger
tooShort; pairminlengthwithrequiredto enforce both presence and minimum length. - UTF-16 Code Units: HTML5 counts character lengths in UTF-16 code units (
string.length), which can differ from human-perceived emojis. validity.tooShort&validity.tooLong: The exact Constraint Validation API flags corresponding to length boundaries.- --