W3docs

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: &euro; &#8364; &#x20AC;</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: &Sigma; &#931; &#x3A3;</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 &copy;, &amp;, &lt;), 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: &#10084; and the same in hex: &#x2764;</p>
<!-- both render as: ❤ -->

Los ceros iniciales son opcionales, por lo que &#x2764; y &#x02764; 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ódigoDecimalBytesCarácter de ejemplo
U+0000 – U+007F0 – 1271 byteA (U+0041)
U+0080 – U+07FF128 – 20472 bytesé (U+00E9), π (U+03C0)
U+0800 – U+FFFF2048 – 655353 bytes (U+20AC), (U+4E2D)
U+10000 – U+10FFFF65536 – 11141114 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 caracteresDecimalHexadecimalMuestra
C0 Controls and Basic Latin0-1270000-007FA B c 7 ?
C1 Controls and Latin-1 Supplement128-2550080-00FFé ñ ü © ÷
Latin Extended-A256-3830100-017Fā Œ ş ž ł
Latin Extended-B384-5910180-024Fƀ Ɛ ǎ ǔ
Spacing Modifiers688-76702B0-02FFˆ ˜ ˘
Diacritical Marks768-8790300-036Fcombining accents
Greek and Coptic880-10230370-03FFα β π Σ Ω
Cyrillic Basic1024-12790400-04FFД Ж и я ё
Cyrillic Supplement1280-13270500-052FҠ ҩ Ӂ
Latin Extended Additional7680-79351E00-1EFFḅ ẁ ẞ ṩ
General Punctuation8192-83032000-206F— … ‹ › †
Currency Symbols8352-839920A0-20CF€ £ ¥ ₽ ₹
Letterlike Symbols8448-85272100-214F™ ℃ № ℅
Arrows8592-87032190-21FF← ↑ → ↓ ↔
Mathematical Operators8704-89592200-22FF∑ √ ∞ ≠ ≤
Box Drawings9472-95992500-257F─ │ ┌ ┐ └
Block Elements9600-96312580-259F░ ▒ ▓ █
Geometric Shapes9632-972725A0-25FF■ ● ▲ ◆ ◇
Miscellaneous Symbols9728-99832600-26FF☀ ☂ ★ ☎ ✿
Dingbats9984-101752700-27BF✂ ✈ ✉ ✏ ❤
Emoji (Emoticons)128512-1285911F600-1F64F😀 😂 😍 🙏 😎

Práctica

Práctica
¿Cuál es el propósito principal de Unicode?
¿Cuál es el propósito principal de Unicode?
Práctica
¿Qué referencia de carácter numérica inserta el carácter en el punto de código U+20AC (el signo del euro)?
¿Qué referencia de carácter numérica inserta el carácter en el punto de código U+20AC (el signo del euro)?
Was this page helpful?