HTML Guides for C1 controls range
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The C1 controls range spans Unicode code points U+0080 through U+009F (decimal 128–159). These are control characters inherited from older encoding standards, and the HTML specification explicitly forbids numeric character references that resolve to them. When the W3C validator encounters a reference like — (decimal 151, which is U+0097), it flags it because these code points are not valid content characters.
Why This Happens
This issue almost always stems from a confusion between the Windows-1252 (or CP-1252) character encoding and Unicode. Windows-1252 is a legacy encoding that repurposes the byte range 0x80–0x9F to store useful characters like curly quotes, em dashes, and the euro sign. In Unicode, however, those same code point positions are reserved as C1 control characters and carry no printable meaning.
When text originally encoded in Windows-1252 gets converted to HTML numeric references byte-by-byte — without proper re-mapping to Unicode — you end up with references like ” instead of the correct ” for a right double quotation mark. The byte value was meaningful in Windows-1252, but the corresponding Unicode code point is a control character.
Why It Matters
- Standards compliance: The HTML specification forbids these references. Browsers may handle them inconsistently, with some silently remapping them and others ignoring them entirely.
- Portability: While some browsers apply the Windows-1252 remapping as a compatibility quirk, this behavior is not guaranteed across all user agents, platforms, or contexts (such as XML or XHTML, where these references cause parse errors).
- Accessibility: Screen readers and other assistive technologies may not interpret C1 control characters at all, resulting in missing or garbled content for users who rely on them.
- Data integrity: If your HTML is processed by tools, APIs, or parsers that follow the spec strictly, these invalid references can cause failures or data loss.
How to Fix It
- Use named character references where available — they’re the most readable option (e.g., —, ’, €).
- Use correct Unicode code points in numeric references if a named reference isn’t available (e.g., — or — for an em dash).
- Use the literal UTF-8 character directly in your source file. If your document is saved as UTF-8 (which it should be), you can simply type —, ', or € directly.
- Audit legacy content that may have been migrated from older systems or databases using Windows-1252 encoding. A search for numeric references in the 128–159 decimal range will find all instances.
Examples
Invalid: C1 control range references
These references resolve to C1 control code points, not the intended characters:
<p>Price: €50</p>
<p>She said, “Hello.”</p>
<p>2020–2024</p>
<p>Wait — what?</p>
<p>It’s a beautiful day.</p>
Fixed: Correct Unicode references
Replace each invalid reference with the proper Unicode code point or named reference:
<p>Price: €50</p>
<p>She said, “Hello.”</p>
<p>2020–2024</p>
<p>Wait — what?</p>
<p>It’s a beautiful day.</p>
Fixed: Using numeric Unicode code points
If you prefer numeric references, use the correct Unicode values:
<p>Price: €50</p>
<p>She said, “Hello.”</p>
<p>2020–2024</p>
<p>Wait — what?</p>
<p>It’s a beautiful day.</p>
Fixed: Using literal UTF-8 characters
The simplest approach — just use the characters directly in a UTF-8 encoded document:
<p>Price: €50</p>
<p>She said, "Hello."</p>
<p>2020–2024</p>
<p>Wait — what?</p>
<p>It's a beautiful day.</p>
Ready to validate your sites?
Start your free trial today.