Codifica UTF-8
UTF sta per Unicode Transformation Format. L'8 indica che vengono usati blocchi a 8 bit per rappresentare un carattere.
Ogni carattere che si digita su una pagina web — una semplice lettera latina, una é accentata, il greco π, il segno dell'euro € o un'emoji — deve essere convertito in byte prima di poter essere memorizzato o trasmesso sulla rete. Le regole che mappano i caratteri in byte si chiamano codifica dei caratteri. Unicode è il catalogo universale che assegna a ogni carattere un numero univoco (un code point), e UTF-8 è la codifica che scrive quei code point come byte. Per un autore HTML, impostare correttamente la codifica è ciò che evita il temuto "mojibake" — output illeggibile come é al posto di é. Questa pagina spiega cos'è UTF-8, come dichiararlo, come inserire qualsiasi carattere Unicode tramite il suo code point, e include una tabella di riferimento degli intervalli Unicode più comuni.
Capitoli correlati: Entità HTML elenca le scorciatoie con nome come
©e&, mentre Set di caratteri HTML spiega come Unicode, UTF-8 e il charset del documento siano correlati tra loro.
Cos'è UTF-8?
Il formato di trasformazione Unicode a 8 bit, chiamato UTF-8, è una codifica dei caratteri a larghezza variabile in grado di codificare tutti gli 1.114.112 code point validi in Unicode con uno o quattro byte a 8 bit. Il numero "8" indica che UTF utilizza blocchi a 8 bit per rappresentare un carattere.
Dal 2009, UTF-8 è la codifica dominante per il World Wide Web, e oggi è utilizzata dalla stragrande maggioranza di tutte le pagine web.
Dichiarare la Codifica in HTML
Un browser non può indovinare in modo affidabile quale codifica usano i tuoi byte, quindi dovresti sempre indicargliela. In HTML5 questo si fa con un singolo tag <meta>, posizionato come prima cosa all'interno di <head> (entro i primi 1024 byte 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>Salva il file come UTF-8 nel tuo editor e dichiara <meta charset="UTF-8">, così i due saranno in accordo. Se manca il <meta charset>, il browser ricorre a un'ipotesi (storicamente windows-1252 per molte lingue occidentali, o un'euristica), ed è esattamente così che compare il testo illeggibile. Per saperne di più, consulta il capitolo sul Tag HTML <meta>.
Perché la Dichiarazione Deve Venire Prima
Un browser non aspetta che l'intero file HTML arrivi prima di iniziare a lavorare — inizia a decodificare i byte in caratteri non appena riceve il primo blocco. Per farlo, deve scegliere una codifica prima di aver letto l'intero documento. La specifica HTML richiede quindi che <meta charset> compaia entro i primi 1024 byte, in modo che il browser possa trovarlo durante quella prima lettura.
Se la dichiarazione della codifica arriva troppo tardi (per esempio, dopo un lungo blocco di commenti o contenuto), il browser avrà già decodificato i byte precedenti usando la sua ipotesi di riserva. Quei byte vengono interpretati in modo errato, e quando la dichiarazione tardiva viene trovata, la pagina potrebbe necessitare un ri-parsing completo — o semplicemente mostrare testo illeggibile. Mantenere <meta charset="UTF-8"> come primo figlio di <head> garantisce che venga rilevato in tempo.
Usare i Code Point Unicode in HTML
Non è necessario digitare direttamente un carattere esotico per utilizzarlo. Qualsiasi code point Unicode può essere inserito con un riferimento numerico di carattere, in decimale (&#NNNN;) o esadecimale (&#xHHHH;). Molti caratteri comuni hanno anche un'entità con nome memorabile.
Ad esempio, il segno dell'euro (code point U+20AC) può essere scritto in tre modi equivalenti:
<p>Euro: € € €</p>
<!-- all three render as: € -->Lo stesso funziona per lettere di qualsiasi alfabeto, come la lettera greca maiuscola sigma (U+03A3):
<p>Greek sigma: Σ Σ Σ</p>
<!-- renders as: Σ -->I riferimenti numerici sono utili per i caratteri difficili da digitare, o per essere espliciti ed evitare ambiguità di codifica. Per l'elenco completo delle scorciatoie con nome (come ©, &, <), consulta Entità HTML.
Riferimenti Numerici di Carattere
Sia &#NNN; (decimale) che &#xHHHH; (esadecimale) identificano un carattere tramite il suo code point Unicode — lo stesso numero che Unicode gli assegna, scritto semplicemente in due basi diverse. La x dopo &# è ciò che contrassegna le cifre come esadecimali. Poiché fanno riferimento direttamente al code point, i riferimenti numerici funzionano per ogni carattere Unicode, anche quelli senza un'entità con nome.
Ad esempio, il cuore nero pieno (code point U+2764, decimale 10084) non ha un'entità con nome ampiamente supportata, ma si può comunque scrivere:
<p>Heart: ❤ and the same in hex: ❤</p>
<!-- both render as: ❤ -->Gli zeri iniziali sono facoltativi, quindi ❤ e ❤ sono equivalenti. L'esadecimale è comodo perché corrisponde alla notazione U+.... che si vede nelle tabelle Unicode.
Suggerimento: Per una panoramica su come si relazionano codifiche, code point e charset del documento, consulta Set di caratteri HTML.
Quanti Byte Occupa un Carattere
UTF-8 è a larghezza variabile: i caratteri con code point piccoli occupano meno byte, così il testo in inglese normale rimane compatto consentendo comunque l'intero intervallo Unicode. Il valore del code point da solo determina quanti byte UTF-8 utilizza per esso, secondo quattro intervalli inclusivi:
| Intervallo code point | Decimale | Byte | Carattere esempio |
|---|---|---|---|
| U+0000 – U+007F | 0 – 127 | 1 byte | A (U+0041) |
| U+0080 – U+07FF | 128 – 2047 | 2 byte | é (U+00E9), π (U+03C0) |
| U+0800 – U+FFFF | 2048 – 65535 | 3 byte | € (U+20AC), 中 (U+4E2D) |
| U+10000 – U+10FFFF | 65536 – 1114111 | 4 byte | 😀 (U+1F600) |
- 1 byte (U+0000–U+007F). Questi byte sono identici ai valori ASCII originali, motivo per cui qualsiasi file ASCII puro è già UTF-8 valido.
- 2 byte (U+0080–U+07FF). Copre la maggior parte delle lettere latine con accenti, oltre al greco, cirillico, ebraico e arabo.
- 3 byte (U+0800–U+FFFF). Include la maggior parte degli altri alfabeti moderni insieme a molti simboli e caratteri CJK (cinese, giapponese, coreano). Questo intervallo arriva fino a U+FFFF incluso.
- 4 byte (U+10000–U+10FFFF). Contiene alfabeti meno comuni, caratteri storici ed emoji, fino al code point Unicode valido più alto, U+10FFFF.
Perché UTF-8 Ha Conquistato il Web
Le codifiche più vecchie come ASCII, Latin-1 (ISO-8859-1) e Windows-1252 usavano ciascuna un singolo byte per carattere, quindi potevano rappresentare al massimo 256 caratteri. Questo va bene per una sola lingua, ma una pagina non può mescolare, ad esempio, francese, russo e giapponese in un unico file. UTF-8 risolve questo problema coprendo ogni carattere in Unicode rimanendo compatibile con ASCII — i primi 128 code point sono mappati agli stessi singoli byte. Questa compatibilità, unita alla compattezza per il testo in inglese, è il motivo per cui UTF-8 ha soppiantato le codifiche legacy a byte singolo ed è diventato il formato predefinito del web.
Il Byte Order Mark (BOM)
Alcuni editor aggiungono all'inizio di un file UTF-8 alcuni byte invisibili, chiamati byte order mark (BOM).
Usare il BOM in HTML?
In UTF-8 il BOM è la sequenza di tre byte EF BB BF. Può fungere da segnale che un file è codificato in UTF-8, ma per HTML è inutile e meglio evitarlo: la dichiarazione <meta charset="UTF-8"> indica già la codifica, e un BOM indesiderato può causare bug sottili (ad esempio, spazio bianco imprevisto prima di <!DOCTYPE>, o problemi con script PHP che emettono output). Se il tuo editor offre la scelta, salva come "UTF-8 senza BOM."
Riferimento agli Intervalli Unicode
L'elenco seguente mostra alcuni blocchi Unicode comunemente usati, ciascuno indicato con il proprio intervallo di code point in decimale ed esadecimale. La colonna degli esempi mostra un glifo del blocco.
| Codici carattere | Decimale | Esadecimale | Esempio |
|---|---|---|---|
| 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 | 😀 😂 😍 🙏 😎 |