HTML Entities vs Unicode Characters: What Is the Difference?

A Unicode character is the actual text value, while an HTML entity or character reference is source syntax that tells the browser which character to insert.

On this page

HTML entities vs Unicode characters at a glance

ConceptUnicode characterHTML character reference
MeaningActual text characterHTML source notation for a character
Exampleéé, é, é
Stored in parsed DOM textCharacterCharacter after parsing
Requires HTML parserNoYes
Works outside HTML automaticallyYes, as textNo
Best general useLiteral UTF-8 textReserved syntax and special escaping
Related to UTF-8 bytesEncoded into bytesParsed first, then encoded as text
Always named?NoCan be named or numeric

Unicode defines the character. HTML defines ways to reference that character in markup. UTF-8 defines how the resulting text is encoded as bytes.

What is a Unicode character?

Unicode assigns numeric code points to text elements. A character may be written directly in a source file, and HTML documents encoded as UTF-8 can contain most Unicode characters literally. Literal Unicode is not an HTML entity. The character's identity is independent of its HTML representation, font rendering is separate from character identity, and one visible grapheme can contain several Unicode code points.

CharacterUnicode nameCode point
ALATIN CAPITAL LETTER AU+0041
éLATIN SMALL LETTER E WITH ACUTEU+00E9
©COPYRIGHT SIGNU+00A9
EURO SIGNU+20AC
😀GRINNING FACEU+1F600

Inspect exact values with What Is a Unicode Code Point? and Unicode Character Inspector.

What is an HTML entity?

Developers often say HTML entity for several related forms. More precisely, HTML has named character references such as ©, decimal numeric character references such as é, and hexadecimal numeric character references such as é. The browser's HTML parser converts references into characters, so the parsed DOM normally contains the resulting character. Entities are HTML syntax, not Unicode encodings. Not every Unicode character has a named HTML reference, but numeric references can represent valid code points under HTML rules.

é
é
é

All three produce é after HTML parsing. Use HTML Entity Encoder and Decoder to test source text.

Named HTML character references

Named references begin with &, normally end with ;, and use names defined by the HTML specification. Some names are case-sensitive. They can improve readability for common symbols, but literal Unicode is often clearer for natural-language text.

Named referenceCharacterCode point
&&U+0026
&lt;<U+003C
&gt;>U+003E
&quot;"U+0022
&apos;'U+0027
&copy;©U+00A9
&nbsp;NO-BREAK SPACEU+00A0
&eacute;éU+00E9

&nbsp; is not an ordinary space; it produces U+00A0. See What Are Invisible Unicode Characters?.

Decimal numeric character references

A decimal numeric character reference starts with &#, uses decimal digits and ends with ;. It represents a Unicode code point under HTML parsing rules, not decimal UTF-8 bytes.

Decimal referenceCharacterCode point
&#65;AU+0041
&#233;éU+00E9
&#169;©U+00A9
&#8364;U+20AC
&#128512;😀U+1F600

Hexadecimal numeric character references

A hexadecimal reference starts with &#x or &#X, uses hexadecimal digits and ends with ;. Hex references often map visibly to U+ notation.

Hex referenceCharacterCode point
&#x41;AU+0041
&#xE9;éU+00E9
&#xA9;©U+00A9
&#x20AC;U+20AC
&#x1F600;😀U+1F600
U+1F600
HTML: &#x1F600;

Literal Unicode vs named vs numeric references

DisplayHTML sourceParsed character
ééU+00E9
é&eacute;U+00E9
é&#233;U+00E9
é&#xE9;U+00E9

The HTML source differs, but parsed text can be identical. UTF-8 source files can contain literal characters directly. Named references depend on HTML's defined name list; numeric references are available for valid code points. Literal Unicode usually improves readability for normal text, while reserved HTML syntax still requires context-aware escaping. Equivalent rendered output does not mean the original HTML source was identical.

Interactive HTML entity and Unicode comparison

This local comparison shows how characters become named, decimal and hexadecimal references, and how references decode back to text without executing markup.

HTML entity and Unicode comparison

Compare literal characters, named references, numeric references, code points and UTF-8 bytes.

Processed locally in your browser

Limit: 2,000 UTF-16 code units. Text stays in your browser.

Open full HTML Entity Encoder/Decoder Open Unicode Character Inspector

When HTML escaping is required

HTML escaping is context-specific. A literal ampersand can begin a character reference, so source text often uses &amp;. A literal less-than sign can begin markup, so text uses &lt;. Greater-than signs are often allowed, though &gt; can improve clarity. A double quote must be escaped inside a double-quoted attribute as &quot;, and an apostrophe must be escaped or avoided in single-quoted attributes with &apos; or an appropriate quote strategy.

Rules differ for text nodes, double-quoted attributes, single-quoted attributes, unquoted attributes, script data, style data and URL values.

Characters that usually do not need entities

With UTF-8 HTML, developers can usually write natural-language text and emoji directly.

<meta charset="utf-8">
<p>café</p>
<p>Русский текст</p>
<p>日本語</p>
<p>😀</p>
Content-Type: text/html; charset=utf-8

Modern HTML supports literal Unicode. Source files should be UTF-8, and HTTP and document charset declarations should agree. Accented characters do not need named entities, and emoji do not require numeric references. Use entities for HTML syntax and special cases, not as a replacement for UTF-8 text.

HTML entities are not UTF-8

Character: é
Code point: U+00E9
HTML reference: &#xE9;
UTF-8 bytes: C3 A9

The processing flow is source syntax first, bytes later: HTML source goes through the HTML parser, character references become Unicode text in the DOM, and the document is encoded or transmitted as UTF-8 bytes. &#xE9; is not a byte sequence. C3 A9 should not be inserted as numeric HTML references for é; &#xC3;&#xA9; produces two different characters. Use Unicode vs UTF-8 and UTF-8 Encoder and Decoder.

HTML entities vs Unicode escape sequences

FormatExample for éParser
HTML named reference&eacute;HTML parser
HTML numeric reference&#xE9;HTML parser
JavaScript Unicode escape\u00E9JavaScript parser
JSON Unicode escape\u00E9JSON parser
Unicode notationU+00E9Human-readable notation
UTF-8 bytesC3 A9UTF-8 decoder

HTML does not use JavaScript \uXXXX escapes in ordinary markup. JavaScript strings embedded in <script> follow JavaScript syntax. JSON embedded in HTML follows both embedding and JSON rules. Parser context must always be known. Read Unicode Escape Sequences Explained and use Unicode Escape Converter.

HTML entities in text nodes

<p>Tom &amp; Jerry</p>
<p>5 &lt; 10</p>

The parser resolves &amp; to & and &lt; to <. The DOM text node contains the character. Reading textContent returns the character, and serializing HTML may escape it again. Literal < must be escaped when intended as text.

HTML entities in attributes

<a title="Tom &amp; Jerry">
    Example
</a>

The parsed attribute value contains Tom & Jerry. Quotes must be escaped when they match the attribute delimiter. HTML escaping does not automatically make a URL safe, and event-handler attributes introduce JavaScript context and should generally be avoided. Modern applications should set attributes through safe APIs or templates.

element.setAttribute("title", userValue);

DOM APIs set values and perform required serialization later.

HTML entities in JavaScript

HTML entities are not interpreted inside ordinary JavaScript strings. JavaScript uses its own string escape rules. &eacute; inside a JavaScript string remains literal text unless passed through an HTML parser, while \u00E9 is JavaScript Unicode escape syntax.

const htmlReference = "&eacute;";
const unicodeEscape = "\u00E9";

console.log(htmlReference); // &eacute;
console.log(unicodeEscape); // é

element.textContent = "&eacute;";

Setting textContent displays literal entity text. Using innerHTML would parse it, but must not be used with untrusted input. Use textContent for untrusted text.

HTML entities in CSS

CSS does not generally use HTML entities. CSS uses CSS escape syntax, and external CSS files do not parse HTML named references. HTML references may be resolved before CSS only when they appear inside HTML markup in a relevant context.

.icon::before {
    content: "\00A9";
}

.wrong::before {
    content: "&copy;";
}

The second rule normally displays literal entity text rather than the copyright symbol. The Unicode escape guide covers CSS escape syntax.

HTML entities in URLs

HTML entity escaping and URL percent encoding solve different problems. In an HTML attribute, ampersands separating query parameters may need HTML escaping, while URL bytes may also require percent encoding.

<a href="/search?q=caf%C3%A9&amp;page=2">
    Search
</a>

%C3%A9 is URL percent encoding of UTF-8 bytes for é. &amp; is HTML escaping for the query separator. The browser parses the entity first; the URL parser then processes the resulting URL. One URL inside HTML can require both URL encoding and HTML escaping. Use URL Encoder and Decoder.

What is double encoding?

Double encoding occurs when already-escaped source is escaped again.

Original entity:
&eacute;

After escaping the ampersand:
&amp;eacute;

The rendered output is literal &eacute;. The browser resolves &amp; to &, and the remaining text is not reparsed as a second entity in the same normal text parsing step. Another example is & encoded once as &amp; and twice as &amp;amp;. Encode once at the output boundary. Do not repeatedly escape already-escaped content.

Missing semicolons and ambiguous references

Character references normally end with ;. Some historical named references may be parsed without a semicolon in limited contexts, but omitting it can create ambiguous parsing. Attribute parsing can behave differently from text parsing, so generated HTML should always include semicolons. Use &amp;, not a semicolon-free shortcut.

Invalid numeric character references

Values above U+10FFFF are invalid, surrogate code points are not valid Unicode scalar values, and U+0000 is treated specially. Some invalid historical values may be replaced according to HTML parsing rules, and the parser may emit U+FFFD or another mapped character. A browser's error recovery is not a validation strategy.

&#x110000;
&#xD800;
&#0;

Named entity availability

Named references are defined by HTML. Some common characters have names, but many Unicode characters do not. Numeric references can represent more valid code points, and literal UTF-8 is usually simpler than memorizing names. XML has a much smaller predefined entity set unless a DTD adds more.

ContextBuilt-in named references
HTMLLarge named-reference set
XMLPrimarily amp, lt, gt, quot, apos

HTML entities and non-breaking spaces

&nbsp; produces U+00A0 NO-BREAK SPACE. It is not equivalent to U+0020 SPACE, affects line wrapping, may appear invisible in copied text, can break equality checks and should not be used repeatedly for page layout. Replacing it with a normal space changes layout semantics. See How to Remove Zero-Width Characters.

HTML entities and normalization

Entity decoding does not normalize Unicode. NFC &#xE9; produces U+00E9. NFD &#x65;&#x301; produces U+0065 U+0301. Both may render as é, but HTML parsing preserves the resulting code-point sequence, and canonically equivalent strings can still compare differently. Normalize separately when the application requires it. Use Unicode Normalization Explained, NFC vs NFD and Unicode Text Compare.

HTML entities and grapheme clusters

One grapheme can require several character references. &#x65;&#x301; represents decomposed é. &#x2665;&#xFE0F; requests emoji-style heart. A family emoji may be written conceptually as &#x1F468;&#x200D;&#x1F469;&#x200D;&#x1F467;&#x200D;&#x1F466;. Each reference maps to one code point, but several code points may form one grapheme cluster. Removing joiners or variation selectors changes rendering. Read What Is a Grapheme Cluster? and use Unicode Sequence Analyzer.

Safe HTML entity encoding

  1. Identify the output context.
  2. Use a trusted HTML template engine.
  3. Escape dynamic text at output time.
  4. Do not pre-escape data before storage.
  5. Avoid manual replacement chains.
  6. Escape ampersands before introducing custom entity text.
  7. Use UTF-8 source files.
  8. Preserve already-correct Unicode.
  9. Do not use innerHTML for untrusted content.
  10. Keep URL encoding separate from HTML escaping.
  11. Keep JavaScript escaping separate from HTML escaping.
  12. Add round-trip and security tests.

Store Unicode text. Escape it for the destination context when rendering.

HTML entity encoding in JavaScript

const element = document.querySelector("#output");
element.textContent = userInput;

textContent prevents markup interpretation. For controlled entity encoding, use a DOM text node and serialization or reuse the project's existing encoder. A simple educational helper for text-node output is:

function escapeHtmlText(text) {
    return text
        .replaceAll("&", "&amp;")
        .replaceAll("<", "&lt;")
        .replaceAll(">", "&gt;");
}

Attribute contexts also require quote handling. This helper is text-node-specific; framework or template escaping is preferable. Decoding must not use untrusted innerHTML.

HTML entity encoding in Python

Template engines should autoescape HTML output. Python also provides standard-library helpers.

from html import escape, unescape

value = '<p title="example">café & tea</p>'
escaped = escape(value, quote=True)
decoded = unescape("&eacute; &#x1F600;")

print(escaped)
print(decoded)

html.escape() escapes HTML-sensitive characters; it does not need to convert all Unicode into numeric references. html.unescape() follows HTML character-reference behavior. Decoded output remains text and must still be escaped when inserted into HTML.

HTML entity encoding in PHP

$escaped = htmlspecialchars(
    $value,
    ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5,
    "UTF-8"
);

$decoded = html_entity_decode(
    $value,
    ENT_QUOTES | ENT_HTML5,
    "UTF-8"
);

ENT_QUOTES handles both quote types, ENT_SUBSTITUTE replaces invalid sequences rather than failing silently, and ENT_HTML5 selects HTML5 entity behavior. Decoded text must be escaped again before HTML output. Do not store pre-escaped HTML unless the data model explicitly requires markup. htmlspecialchars() and htmlentities() serve different purposes; normal Unicode text usually does not need broad entity conversion.

HTML entities in Jinja2

UnicodeNow uses Jinja2 templates, so autoescaping should remain enabled for HTML templates. Dynamic user text should render through ordinary escaped interpolation. Do not apply |safe to untrusted content. Article HTML generated from trusted Markdown must pass through the project's sanitization policy, values should not be pre-escaped in the database, and trust boundaries should be clear to avoid double escaping.

<p>{{ user_text }}</p>
<p>{{ user_text | safe }}</p>

The second form is appropriate only when content is trusted and sanitized.

Common HTML entity mistakes

Converting every non-ASCII character into an entity

Literal UTF-8 is usually clearer.

Treating HTML entities as UTF-8 bytes

They are parser syntax for code points.

Writing UTF-8 bytes as numeric references

&#xC3;&#xA9; is not é.

Using JavaScript escapes in HTML

\u00E9 is not interpreted in normal HTML text.

Using HTML entities in CSS

External CSS does not parse HTML references.

Forgetting context-specific escaping

Text and attribute contexts differ.

Decoding entities before rendering without re-escaping

This can create injection risks.

Storing pre-escaped text

This encourages double encoding.

Using innerHTML to decode untrusted entities

This can parse active markup.

Double encoding ampersands

&amp; becomes &amp;amp;.

Omitting semicolons

This can cause ambiguous parsing.

Treating &nbsp; as an ordinary space

It has different line-breaking behavior.

Confusing URL encoding with HTML escaping

Both may be required independently.

Practical debugging workflow

  1. Preserve the original source.
  2. Determine whether you are viewing source, DOM text or serialized HTML.
  3. Identify the parser context.
  4. Inspect literal characters and references.
  5. Decode one layer at a time.
  6. Check for double encoding.
  7. Inspect code points.
  8. Check UTF-8 bytes separately.
  9. Verify HTML escaping context.
  10. Check URL or JavaScript encoding separately.
  11. Check normalization.
  12. Add round-trip tests.

Use Unicode Escape Converter, Text to Unicode Code Points, Unicode Code Points to Text and Unicode Character Inspector.

Try these UnicodeNow tools

These tools encode and decode references, inspect Unicode values and compare parsed text against source representations.

Unicode Character Inspector

Inspect each Unicode character, encoding, category, script and normalization form.

UnicodeProcessed locally

Unicode Escape Converter

Convert text to and from Unicode escape sequences and numeric entities.

DeveloperProcessed locally

Unicode Sequence Analyzer

Analyze code points, grapheme clusters, bytes, scripts and directionality.

UnicodeProcessed locally

URL Encoder and Decoder

Encode and decode URL components, full URLs and form-style strings.

EncodingProcessed locally

Unicode Text Compare

Compare strings exactly and after Unicode normalization.

Text ComparisonProcessed locally

Frequently asked questions

What is the difference between an HTML entity and a Unicode character?

A Unicode character is the actual text value. An HTML entity or character reference is HTML source syntax that resolves to a character.

Is &eacute; the same as é?

After HTML parsing, both normally produce U+00E9.

Is &#233; the same as &#xE9;?

Yes. One uses decimal and the other hexadecimal notation for the same code point.

Are HTML entities UTF-8?

No. They are HTML syntax. UTF-8 is a byte encoding.

Do accented characters need HTML entities?

Usually no. Literal UTF-8 is appropriate in modern HTML.

Does emoji need to be written as an HTML entity?

No. Literal emoji is valid in UTF-8 HTML.

Which characters must be escaped in HTML?

At minimum, ampersands and less-than signs require attention in text, while quotes require escaping in matching attribute contexts.

Is &nbsp; the same as a normal space?

No. It produces U+00A0 NO-BREAK SPACE.

Can HTML entities work in JavaScript strings?

They remain literal text unless processed by an HTML parser. JavaScript uses its own escapes.

Can HTML entities work in CSS?

Not in normal external CSS syntax. CSS uses CSS escapes.

What is double-encoded HTML?

Already-escaped text has been escaped again, such as &amp; becoming &amp;amp;.

Should HTML entities be stored in a database?

Usually store Unicode text and escape it when rendering.

Is decoding HTML entities safe?

Decoding produces text that must still be escaped for its destination context.

Can numeric references represent any Unicode character?

They can represent valid code points under HTML parsing rules, but invalid values are handled through parser error recovery.

Does entity decoding normalize Unicode?

No.

References