Why do the < and & characters carry special meaning in HTML?

HTML is a markup language, and as the browser reads a page's source it is constantly looking for the < character: the moment that character appears, it assumes a new tag has begun. The & character carries a special meaning in the same way, because it marks the beginning of an entity reference. That is why, when you want to show the <, > and & characters on a page exactly as they are (as literal text), you cannot simply type them — the browser will try to interpret them as markup.

A similar problem arises inside attribute values: if you delimit a value with double quotes, a double quote inside it ends the value early; if you delimit it with single quotes, a single quote creates the same problem instead. So special characters are not limited to < , > and & — depending on the context, double quotes and single quotes join the set of characters that have to be encoded.

Named entity or numeric character reference?

There are two different entity forms. Named entities consist of short, easily read names: &amp; corresponds to the & character, &lt; to the < character and &gt; to the > character. Numeric character references, on the other hand, use a character's Unicode code point directly: they are written as &#NNN; in decimal or &#xHHH; in hexadecimal. For example, the & character can also be written as &#38; in decimal or &#x26; in hexadecimal — the browser resolves both to the same character.

The strength of the numeric form is that it also works for characters with no named counterpart: you can encode any Unicode character with the &#NNN; rule as long as you know its code point. For instance, a named entity &euro; is defined for the euro sign (€), but you do not have to know that named form by heart — you can write the same character as &#8364; (decimal) or &#x20AC; (hexadecimal). For the apostrophe there is no widely used named entity; that is why in practice it is almost always encoded in the numeric form &#39;.

CharacterNamed entityNumeric (decimal)Numeric (hexadecimal)
&lt;&amp;lt;&amp;#60;&amp;#x3C;
&gt;&amp;gt;&amp;#62;&amp;#x3E;
&amp;&amp;amp;&amp;#38;&amp;#x26;
double quote (inside an attribute)&amp;quot;&amp;#34;&amp;#x22;
single quote / apostropheno widely used named form&amp;#39;&amp;#x27;
©&amp;copy;&amp;#169;&amp;#xA9;

Where does HTML entity encoding help in real life?

Displaying user content safely

When a website prints a comment, forum post or profile detail written by a user onto the page, that text may contain characters such as < or & — sometimes innocently (someone writing 5 < 10 in a comment), sometimes maliciously (an attempt to insert a <script> tag). Converting that text to entities before printing it makes the browser display it as plain text rather than as a real tag or executable code. This is a basic security practice called output encoding, and it is one of the measures taken against XSS (cross-site scripting) attacks. It is not sufficient on its own in every situation — if a value is placed inside an HTML attribute or inside a <script> block, different encoding rules are required — but it is the standard, safe way to display text in an element body.

Showing code snippets on a page

You run into the same problem when you want to show an HTML or JavaScript code example in a technical article or in documentation. If the code contains <, > or & and you write them as they are, the browser mistakes them for real tags and tries to interpret them, so part of the code becomes invisible or the rest of the page breaks. That is why code text to be shown inside a <pre> or <code> block also has to be converted to entities first.

Common encoding mistakes

  • Encoding the & character last: If you replace characters by hand, in order, turning < and > into &lt; / &gt; first and leaving & for last, the & signs inside the entities you have just created get encoded again; the result is broken, double-encoded text such as &amp;lt;. The right approach: always encode the & character first, or use a function that replaces all characters in a single pass.
  • Re-encoding text that is already encoded: If a text is already stored in the database in the form &amp; (that is, encoded once) and you encode it again at render time, another prefix is added at every layer and the result is text that grows progressively more broken and needlessly long. Encoding must be applied only to raw data, and only once.
  • Confusing the HTML context with the JavaScript string context: HTML entity encoding only helps in areas the browser parses as HTML (element bodies, attribute values). If a value is placed into a JavaScript string inside a <script> block, the browser parses that block as JavaScript, not HTML; an HTML entity inside it is therefore not decoded and stays as literal text. For values to be embedded in a JS string, backslash escaping is used instead.
  • Assuming there will always be a named entity: If you want to encode a little-known or rare symbol, it may not always have a named counterpart. In that case the numeric form — &#NNN; or &#xHHH; — is a universal fallback that always works.

A quick fix with the KEYDAL HTML Entity Encoder

Applying the rules above by hand is error-prone, particularly because of details such as encoding the & character in the right order. KEYDAL's HTML entity encoder/decoder tool converts plain text in one click into the correct entities for the five most common XML-safe characters (&amp; &lt; &gt; &quot; &#39;) plus a few common symbols (© ® ™ € £ ¥); on the decode side it additionally resolves all numeric character references (&#NNN; and &#xHHH;) in full. The tool runs entirely in your browser, and the text you enter is never sent to any server.