Кодировка UTF-8
UTF расшифровывается как Unicode Transformation Format. Цифра «8» означает, что для представления символа используются 8-битные блоки.
Каждый символ, который вы вводите на веб-странице — обычная латинская буква, буква с ударением é, греческая π, знак евро € или эмодзи — должен быть преобразован в байты, прежде чем его можно будет сохранить или передать по сети. Правила, которые сопоставляют символы с байтами, называются кодировкой символов. Unicode — это универсальный каталог, присваивающий каждому символу уникальный номер (кодовую точку), а UTF-8 — это кодировка, записывающая эти кодовые точки в виде байтов. Для HTML-разработчика правильная установка кодировки — это то, что защищает от пресловутых «кракозябров» — искажённого вывода вида é вместо é. На этой странице объясняется, что такое UTF-8, как её объявлять, как вставлять любой символ Unicode по его кодовой точке, а также приводится справочная таблица распространённых диапазонов Unicode.
Связанные главы: HTML Entities содержит именованные сокращения вроде
©и&, а HTML Character Sets объясняет, как Unicode, UTF-8 и кодировка документа связаны между собой.
Что такое UTF-8?
8-битный формат преобразования Unicode, называемый UTF-8, — это кодировка символов переменной ширины, способная кодировать все 1 114 112 допустимых кодовых точек Unicode с помощью одного-четырёх 8-битных байтов. Цифра «8» означает, что UTF использует 8-битные блоки для представления символа.
С 2009 года UTF-8 является ведущей кодировкой для Всемирной паутины, и сегодня её использует подавляющее большинство всех веб-страниц.
Объявление кодировки в HTML
Браузер не может надёжно угадать, какую кодировку используют ваши байты, поэтому вы всегда должны сообщать ему об этом. В HTML5 это делается с помощью одного тега <meta>, помещённого первым внутри <head> (в пределах первых 1024 байтов документа):
<!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>Сохраните файл в UTF-8 в вашем редакторе и объявите <meta charset="UTF-8">, и они будут согласованы. Если <meta charset> отсутствует, браузер прибегает к угадыванию (исторически windows-1252 для многих западных локалей или эвристика), что и является причиной появления искажённого текста. Подробнее читайте в главе HTML <meta> Tag.
Почему объявление должно идти в начале
Браузер не ждёт полной загрузки HTML-файла, прежде чем начать работу — он начинает декодировать байты в символы, как только поступает первый фрагмент. Для этого ему необходимо выбрать кодировку до того, как весь документ будет прочитан. Спецификация HTML поэтому требует, чтобы <meta charset> появлялся в пределах первых 1024 байтов, чтобы браузер мог найти его в ходе начального прохода.
Если вы объявляете кодировку слишком поздно (например, после длинного блока комментариев или контента), браузер уже декодирует предыдущие байты, используя свой резервный вариант. Эти байты интерпретируются неверно, и к тому моменту, когда обнаруживается позднее объявление, страница может потребовать полного повторного разбора — или просто отобразит искажённый текст. Размещение <meta charset="UTF-8"> самым первым дочерним элементом <head> гарантирует, что оно будет найдено вовремя.
Использование кодовых точек Unicode в HTML
Вам не нужно вводить экзотический символ напрямую, чтобы его использовать. Любую кодовую точку Unicode можно вставить с помощью числовой ссылки на символ — в десятичной (&#NNNN;) или шестнадцатеричной (&#xHHHH;) форме. Многие распространённые символы также имеют запоминающееся именованное мнемоническое обозначение.
Например, знак евро (кодовая точка U+20AC) можно записать тремя эквивалентными способами:
<p>Euro: € € €</p>
<!-- all three render as: € -->То же самое работает для букв из любого алфавита, например для греческой заглавной буквы сигма (U+03A3):
<p>Greek sigma: Σ Σ Σ</p>
<!-- renders as: Σ -->Числовые ссылки удобны для символов, которые сложно ввести с клавиатуры, или чтобы быть точным и избежать неоднозначности кодировки. Полный список именованных сокращений (таких как ©, &, <) смотрите в разделе HTML Entities.
Числовые ссылки на символы
И &#NNN; (десятичная), и &#xHHHH; (шестнадцатеричная) форма называют символ по его кодовой точке Unicode — тому же числу, которое Unicode ему присваивает, просто записанному в разных системах счисления. Символ x после &# указывает на то, что цифры шестнадцатеричные. Поскольку они ссылаются непосредственно на кодовую точку, числовые ссылки работают для каждого символа Unicode, даже для тех, у которых нет именованного обозначения.
Например, жирное чёрное сердце (кодовая точка U+2764, десятичное 10084) не имеет широко поддерживаемого именованного обозначения, но его всё равно можно записать:
<p>Heart: ❤ and the same in hex: ❤</p>
<!-- both render as: ❤ -->Ведущие нули необязательны, поэтому ❤ и ❤ эквивалентны. Шестнадцатеричная запись удобна, поскольку совпадает с нотацией U+...., используемой в таблицах Unicode.
Совет: Обзор того, как кодировки, кодовые точки и кодировка документа связаны между собой, смотрите в разделе HTML Character Sets.
Сколько байтов занимает символ
UTF-8 имеет переменную ширину: символы с малыми кодовыми точками занимают меньше байтов, поэтому обычный английский текст остаётся компактным, при этом поддерживается полный диапазон Unicode. Значение кодовой точки само по себе определяет, сколько байтов UTF-8 использует для неё, согласно четырём включительным диапазонам:
| Диапазон кодовых точек | Десятичный | Байты | Пример символа |
|---|---|---|---|
| U+0000 – U+007F | 0 – 127 | 1 байт | A (U+0041) |
| U+0080 – U+07FF | 128 – 2047 | 2 байта | é (U+00E9), π (U+03C0) |
| U+0800 – U+FFFF | 2048 – 65535 | 3 байта | € (U+20AC), 中 (U+4E2D) |
| U+10000 – U+10FFFF | 65536 – 1114111 | 4 байта | 😀 (U+1F600) |
- 1 байт (U+0000–U+007F). Эти байты идентичны исходным значениям ASCII, поэтому любой файл в кодировке ASCII уже является допустимым UTF-8.
- 2 байта (U+0080–U+07FF). Охватывает большинство латинских букв с диакритическими знаками, а также греческий, кириллический, еврейский и арабский алфавиты.
- 3 байта (U+0800–U+FFFF). Включает большинство других современных письменностей, а также многие символы и символы CJK (китайские, японские, корейские). Этот диапазон простирается вплоть до U+FFFF включительно.
- 4 байта (U+10000–U+10FFFF). Содержит редко используемые письменности, исторические символы и эмодзи — вплоть до наивысшей допустимой кодовой точки Unicode U+10FFFF.
Почему UTF-8 завоевала веб
Старые кодировки, такие как ASCII, Latin-1 (ISO-8859-1) и Windows-1252, использовали один байт на символ, поэтому могли представлять не более 256 символов. Для одного языка этого достаточно, но страница не может совмещать, например, французский, русский и японский в одном файле. UTF-8 решает эту проблему, охватывая каждый символ Unicode, оставаясь при этом обратно совместимой с ASCII — первые 128 кодовых точек отображаются на те же самые однобайтовые значения. Именно эта совместимость вместе с компактностью для английского текста стала причиной того, что UTF-8 вытеснила устаревшие однобайтовые кодировки и стала стандартом веба.
Метка порядка байтов (BOM)
Некоторые редакторы добавляют несколько невидимых байтов в самое начало UTF-8 файла — это называется меткой порядка байтов (BOM).
Следует ли использовать BOM в HTML?
В UTF-8 BOM представляет собой трёхбайтовую последовательность EF BB BF. Она может служить сигналом того, что файл закодирован в UTF-8, но для HTML она не нужна и лучше её избегать: ваше объявление <meta charset="UTF-8"> уже указывает кодировку, а случайная BOM может вызвать трудноуловимые ошибки (например, неожиданные пробелы перед <!DOCTYPE> или нарушение работы PHP-скриптов, выводящих данные). Если ваш редактор предлагает выбор, сохраните файл как «UTF-8 без BOM».
Справочник по диапазонам Unicode
В приведённом ниже списке показаны некоторые часто используемые блоки Unicode с указанием диапазонов кодовых точек в десятичном и шестнадцатеричном форматах. В столбце «Образец» показан один глиф из блока.
| Коды символов | Десятичный | Шестнадцатеричный | Образец |
|---|---|---|---|
| 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 | 😀 😂 😍 🙏 😎 |