Codificación UTF-8
UTF significa Formato de Transformación Unicode. El '8' indica que usa bloques de 8 bits para representar un carácter.
Cada carácter que escribes en una página web — una letra latina simple, una é acentuada, una π griega, el signo del euro €, o un emoji — debe convertirse en bytes antes de poder almacenarse o enviarse por la red. Las reglas que asignan caracteres a bytes se denominan codificación de caracteres. Unicode es el catálogo universal que asigna a cada carácter un número único (un punto de código), y UTF-8 es la codificación que escribe esos puntos de código como bytes. Como autor de HTML, tener la codificación correcta es lo que te separa del temido "mojibake" — texto ilegible como é donde debería aparecer é. Esta página explica qué es UTF-8, cómo declararlo, cómo insertar cualquier carácter Unicode por su punto de código, e incluye una tabla de referencia de rangos Unicode comunes.
Capítulos relacionados: Entidades HTML lista los atajos con nombre como
©y&, y Conjuntos de caracteres HTML explica cómo se relacionan Unicode, UTF-8 y el conjunto de caracteres del documento.
¿Qué es UTF-8?
El Formato de Transformación Unicode de 8 bits, llamado UTF-8, es una codificación de caracteres de ancho variable que puede codificar todos los 1,114,112 puntos de código válidos en Unicode con uno a cuatro bytes de 8 bits. El número "8" significa que UTF utiliza bloques de 8 bits para representar un carácter.
Desde 2009, UTF-8 ha sido la codificación predominante para la World Wide Web, y hoy en día es utilizada por la gran mayoría de todas las páginas web.
Declarar la Codificación en HTML
Un navegador no puede adivinar de manera confiable qué codificación usan tus bytes, por lo que siempre debes indicárselo. En HTML5 esto se hace con una única etiqueta <meta>, colocada como lo primero dentro de <head> (dentro de los primeros 1024 bytes del documento):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>UTF-8 example</title>
</head>
<body>
<p>Prices: €10 · Greek letter: π · Smiley: 😀</p>
</body>
</html>Guarda el archivo como UTF-8 en tu editor y declara <meta charset="UTF-8">, y ambos coincidirán. Si falta el <meta charset>, el navegador recurre a una suposición (históricamente windows-1252 para muchas configuraciones regionales occidentales, o una heurística), que es exactamente cómo aparece el texto ilegible. Aprende más en el capítulo Etiqueta HTML <meta>.
Por Qué la Declaración Debe Aparecer al Principio
Un navegador no espera a que llegue todo el archivo HTML antes de empezar a trabajar — comienza a decodificar bytes en caracteres tan pronto como llega el primer fragmento. Para hacer eso, debe elegir una codificación antes de haber leído el documento completo. Por ello, la especificación HTML requiere que <meta charset> aparezca dentro de los primeros 1024 bytes, para que el navegador pueda encontrarlo durante esa pasada inicial.
Si declaras la codificación demasiado tarde (por ejemplo, después de un bloque largo de comentarios o contenido), el navegador ya habrá decodificado los bytes anteriores usando su suposición de respaldo. Esos bytes se interpretan incorrectamente, y cuando se encuentra la declaración tardía, es posible que la página necesite un análisis completo de nuevo — o simplemente muestre texto ilegible. Mantener <meta charset="UTF-8"> como el primer hijo de <head> garantiza que se vea a tiempo.
Usar Puntos de Código Unicode en HTML
No necesitas escribir un carácter exótico directamente para usarlo. Cualquier punto de código Unicode puede insertarse con una referencia de carácter numérica, en decimal (&#NNNN;) o hexadecimal (&#xHHHH;). Muchos caracteres comunes también tienen una entidad con nombre fácil de recordar.
Por ejemplo, el signo del euro (punto de código U+20AC) puede escribirse de tres formas equivalentes:
<p>Euro: € € €</p>
<!-- all three render as: € -->Lo mismo funciona para letras de cualquier sistema de escritura, como la letra griega mayúscula sigma (U+03A3):
<p>Greek sigma: Σ Σ Σ</p>
<!-- renders as: Σ -->Las referencias numéricas son útiles para caracteres difíciles de escribir, o para ser explícito y evitar ambigüedad en la codificación. Para la lista completa de atajos con nombre (como ©, &, <), consulta Entidades HTML.
Referencias de Caracteres Numéricas
Tanto &#NNN; (decimal) como &#xHHHH; (hexadecimal) nombran un carácter por su punto de código Unicode — el mismo número que Unicode le asigna, simplemente escrito en dos bases diferentes. La x después de &# es lo que marca los dígitos como hexadecimales. Como referencian el punto de código directamente, las referencias numéricas funcionan para todos los caracteres Unicode, incluso aquellos sin entidad con nombre.
Por ejemplo, el corazón negro sólido (punto de código U+2764, decimal 10084) no tiene entidad con nombre ampliamente compatible, pero aun así puedes escribirlo:
<p>Heart: ❤ and the same in hex: ❤</p>
<!-- both render as: ❤ -->Los ceros iniciales son opcionales, por lo que ❤ y ❤ son equivalentes. El hexadecimal es conveniente porque coincide con la notación U+.... que ves en las tablas Unicode.
Consejo: Para una descripción general de cómo se relacionan las codificaciones, los puntos de código y el conjunto de caracteres del documento, consulta Conjuntos de caracteres HTML.
Cuántos Bytes Ocupa un Carácter
UTF-8 es de ancho variable: los caracteres con puntos de código pequeños ocupan menos bytes, por lo que el texto en inglés simple permanece compacto mientras se permite el rango completo de Unicode. El valor del punto de código por sí solo determina cuántos bytes usa UTF-8 para él, según cuatro rangos inclusivos:
| Rango de puntos de código | Decimal | Bytes | Carácter de ejemplo |
|---|---|---|---|
| U+0000 – U+007F | 0 – 127 | 1 byte | A (U+0041) |
| U+0080 – U+07FF | 128 – 2047 | 2 bytes | é (U+00E9), π (U+03C0) |
| U+0800 – U+FFFF | 2048 – 65535 | 3 bytes | € (U+20AC), 中 (U+4E2D) |
| U+10000 – U+10FFFF | 65536 – 1114111 | 4 bytes | 😀 (U+1F600) |
- 1 byte (U+0000–U+007F). Estos bytes son idénticos a los valores ASCII originales, por lo que cualquier archivo ASCII simple ya es UTF-8 válido.
- 2 bytes (U+0080–U+07FF). Cubre la mayoría de las letras latinas con acentos, además del griego, cirílico, hebreo y árabe.
- 3 bytes (U+0800–U+FFFF). Incluye la mayoría de los demás sistemas de escritura modernos junto con muchos símbolos y caracteres CJK (chino, japonés, coreano). Este rango llega hasta U+FFFF inclusive.
- 4 bytes (U+10000–U+10FFFF). Contiene sistemas de escritura menos comunes, caracteres históricos y emojis, hasta el punto de código Unicode válido más alto, U+10FFFF.
Por Qué UTF-8 Ganó la Web
Las codificaciones más antiguas como ASCII, Latin-1 (ISO-8859-1) y Windows-1252 cada una usaba un byte por carácter, por lo que solo podían representar hasta 256 caracteres. Eso está bien para un idioma, pero una página no puede mezclar, por ejemplo, francés, ruso y japonés en un solo archivo. UTF-8 soluciona esto cubriendo todos los caracteres de Unicode mientras mantiene la compatibilidad retroactiva con ASCII — los primeros 128 puntos de código se asignan exactamente a los mismos bytes individuales. Esa compatibilidad, junto con su compacidad para texto en inglés, es la razón por la que UTF-8 desplazó a las codificaciones de un solo byte heredadas y se convirtió en el estándar predeterminado de la web.
La Marca de Orden de Bytes (BOM)
Algunos editores anteponen unos pocos bytes invisibles al inicio de un archivo UTF-8, llamados marca de orden de bytes (BOM).
¿Deberías Usar un BOM en HTML?
En UTF-8, el BOM es la secuencia de tres bytes EF BB BF. Puede actuar como señal de que un archivo está codificado en UTF-8, pero para HTML es innecesario y es mejor evitarlo: tu declaración <meta charset="UTF-8"> ya indica la codificación, y un BOM erróneo puede causar errores sutiles (por ejemplo, espacio en blanco inesperado antes de <!DOCTYPE>, o romper scripts PHP que emiten salida). Si tu editor ofrece la opción, guarda como "UTF-8 sin BOM".
Referencia de Rangos Unicode
La lista a continuación muestra algunos bloques Unicode de uso común, cada uno dado por su rango de puntos de código decimal y hexadecimal. La columna de muestra muestra un glifo del bloque.
| Códigos de caracteres | Decimal | Hexadecimal | Muestra |
|---|---|---|---|
| C0 Controls and Basic Latin | 0-127 | 0000-007F | A B c 7 ? |
| C1 Controls and Latin-1 Supplement | 128-255 | 0080-00FF | é ñ ü © ÷ |
| Latin Extended-A | 256-383 | 0100-017F | ā Œ ş ž ł |
| Latin Extended-B | 384-591 | 0180-024F | ƀ Ɛ ǎ ǔ |
| Spacing Modifiers | 688-767 | 02B0-02FF | ˆ ˜ ˘ |
| Diacritical Marks | 768-879 | 0300-036F | combining accents |
| Greek and Coptic | 880-1023 | 0370-03FF | α β π Σ Ω |
| Cyrillic Basic | 1024-1279 | 0400-04FF | Д Ж и я ё |
| Cyrillic Supplement | 1280-1327 | 0500-052F | Ҡ ҩ Ӂ |
| Latin Extended Additional | 7680-7935 | 1E00-1EFF | ḅ ẁ ẞ ṩ |
| General Punctuation | 8192-8303 | 2000-206F | — … ‹ › † |
| Currency Symbols | 8352-8399 | 20A0-20CF | € £ ¥ ₽ ₹ |
| Letterlike Symbols | 8448-8527 | 2100-214F | ™ ℃ № ℅ |
| Arrows | 8592-8703 | 2190-21FF | ← ↑ → ↓ ↔ |
| Mathematical Operators | 8704-8959 | 2200-22FF | ∑ √ ∞ ≠ ≤ |
| Box Drawings | 9472-9599 | 2500-257F | ─ │ ┌ ┐ └ |
| Block Elements | 9600-9631 | 2580-259F | ░ ▒ ▓ █ |
| Geometric Shapes | 9632-9727 | 25A0-25FF | ■ ● ▲ ◆ ◇ |
| Miscellaneous Symbols | 9728-9983 | 2600-26FF | ☀ ☂ ★ ☎ ✿ |
| Dingbats | 9984-10175 | 2700-27BF | ✂ ✈ ✉ ✏ ❤ |
| Emoji (Emoticons) | 128512-128591 | 1F600-1F64F | 😀 😂 😍 🙏 😎 |