
Computers store text as numbers, and a character encoding is the agreed-upon table that says “65 means A.” For decades that table was ASCII. Today it is almost always UTF-8. Understanding the difference explains why you sometimes see “é” where an accented é should be, and how to stop it happening.
ASCII: elegant, but tiny
ASCII, from the 1960s, uses 7 bits to cover 128 characters: the English alphabet in both cases, digits, punctuation, and a few control codes. It is beautifully simple and still underpins everything — but 128 slots cannot hold accented letters, Greek, Cyrillic, Arabic, Chinese, or emoji. For an English-only world that was fine; for the actual world it was not nearly enough.
Unicode and UTF-8: room for everyone
Unicode is the giant catalogue that assigns a unique number (a code point) to every character in every writing system — over 149,000 of them, emoji included. UTF-8 is the clever way we store those numbers as bytes. Its masterstroke is backward compatibility: the first 128 code points are encoded identically to ASCII, so every old ASCII file is already valid UTF-8. Characters beyond that use two, three, or four bytes as needed, so common English text stays compact while the door stays open for every language.
Why you see garbled text (mojibake)
“Mojibake” — that soup of  and à symbols — happens when text is written in one encoding and read in another. A file saved as UTF-8 but opened as Windows-1252 (or vice versa) mangles every non-ASCII character. The single most common web cause is a page that omits the declaration. Fixing it is usually one line in the <head>: <meta charset="UTF-8">, plus making sure your database and server both speak UTF-8 end to end.
The practical rules
The guidance today is refreshingly simple: use UTF-8 everywhere. Save source files as UTF-8, declare charset=UTF-8 in HTML, set your database and connection to utf8mb4 (the full-emoji-capable variant in MySQL), and send the Content-Type: text/html; charset=utf-8 header. Do that consistently and the whole class of encoding bugs simply disappears. When you do hit garbled characters, the fix is almost always finding the one place in the chain that is not UTF-8.
Why UTF-8 won
UTF-8 succeeded because of a design decision that sounds almost too convenient: the first 128 code points are encoded exactly as ASCII encodes them, as single bytes with the same values. Any file containing only unaccented English text is simultaneously valid ASCII and valid UTF-8, byte for byte identical.
That backwards compatibility meant existing tools, protocols and files kept working during the transition. A system that only understood ASCII could still read the ASCII portion of a UTF-8 document, and software could be upgraded gradually rather than all at once. Competing encodings that broke this property never achieved the same adoption.
How the variable length actually works
UTF-8 uses one to four bytes per character, and the leading byte announces how many follow. Characters in the ASCII range use one byte. Most Latin letters with accents, plus Greek, Cyrillic, Hebrew and Arabic, use two. The great majority of Chinese, Japanese and Korean characters use three. Emoji and rarer historical scripts use four.
The practical consequence is that character count and byte count are different numbers, and code that confuses them produces bugs. A string of five emoji is five characters but twenty bytes. A database column declared as twenty bytes will not hold it, and a naive truncation at the byte level can slice a character in half and produce the replacement character that appears as a black diamond with a question mark.
The mojibake problem, and how to read it
When text appears as é where é should be, the cause is almost always the same: the bytes were written as UTF-8 but read as a single-byte encoding such as Latin-1 or Windows-1252. The two-byte UTF-8 sequence for é is interpreted as two separate single-byte characters, and you see both.
The pattern is diagnostic. Seeing à followed by another symbol nearly always means UTF-8 misread as Latin-1. Seeing a literal question mark in a diamond usually means the opposite: a character arrived that the target encoding genuinely cannot represent, so it was replaced rather than mangled. The first case is recoverable because the original bytes survive; the second often is not, because information was discarded at conversion time.
Getting it right
Declare UTF-8 explicitly at every layer rather than relying on defaults, which vary by platform and version. In HTML that means <meta charset="utf-8"> early in the head. In HTTP it means a Content-Type header that includes the charset. In databases it means choosing a genuinely full UTF-8 collation, and in MySQL specifically it means utf8mb4 rather than the older utf8, which stores only three bytes per character and silently fails on emoji and some Chinese characters.
Common questions
Is UTF-8 better than ASCII?
UTF-8 is a superset of ASCII — it can represent every character ASCII can, plus every other language and emoji. For anything beyond plain English, UTF-8 is essential.
Why does my text show weird symbols like é?
That is mojibake: the text was saved in one encoding and read in another. Declare UTF-8 consistently in your files, HTML, database and server to fix it.
What is the difference between Unicode and UTF-8?
Unicode is the catalogue that assigns a number to every character; UTF-8 is one way to store those numbers as bytes. UTF-8 is the most common Unicode encoding on the web.
Should I still care about ASCII?
ASCII still matters as the foundation UTF-8 is built on, but you should save and serve new content as UTF-8 to avoid encoding problems.