Déclarer un encodage de caractères en HTML

Question

Comment devrais-je déclarer l’encodage de mon fichier HTML ?

Vous devriez toujours préciser l’encodage utilisé dans une page HTML ou XML pour éviter une interprétation erronée des caractères de votre contenu. La question de la lisibilité ne se pose pas seulement pour votre public : les machines ont, elles aussi, de plus en plus besoin de comprendre vos données. Une déclaration d’encodage de caractères est également nécessaire au traitement des caractères non ASCII saisis par les utilisateurs dans des formulaires, présents dans les URL générées par des scripts, et ainsi de suite. Cet article décrit la marche à suivre pour un fichier HTML.

Si vous avez besoin de mieux comprendre en quoi consistent les caractères et les encodages de caractères, consultez l’article Encodages de caractères pour débutants. Pour obtenir des informations sur la déclaration des encodages dans les feuilles de style CSS, consultez l’article Déclarations d’encodage de caractères en CSS.

Réponse courte

Déclarez systématiquement l’encodage de votre document à l’aide d’un élément meta doté soit de l’attribut charset seul, soit des attributs http-equiv et content (une solution appelée directive pragma). La déclaration devrait se trouver au début du fichier et tenir entièrement dans les 1024 premiers octets. Il est donc préférable de la placer juste après la balise ouvrante head.

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
...
<!DOCTYPE html>
<html lang="fr">
<head>
<meta http-equiv="Content-Type" 
      content="text/html; charset=utf-8">
...

Peu importe quelle solution vous choisissez. Vous pourriez préférer la première solution, plus courte. Peu importe également que vous saisissiez UTF-8 ou utf-8.

Vous devriez toujours utiliser l’encodage de caractères UTF-8. (Pour rappel, vous devez non seulement déclarer cet encodage, mais aussi enregistrer votre contenu en UTF-8.) Si vous ne pouvez vraiment pas utiliser cet encodage, vous aurez un certain nombre de choses à prendre en compte.

Si vous avez accès aux paramètres du serveur, vous devriez également vous demander si l’utilisation de l’en-tête HTTP aurait du sens. Notez cependant que l’en-tête HTTP prévaut sur les déclarations réalisées à l’intérieur du document via l’élément meta ; par conséquent, lorsque vous créez du contenu, vous devriez toujours vous demander si l’encodage de caractères est déjà déclaré dans l’en-tête HTTP. S’il l’est déjà, l’élément meta devra déclarer le même encodage.

Pour détecter tout encodage envoyé par l’en-tête HTTP, vous pouvez utiliser le Vérificateur d’internationalisation.

Réponse détaillée

Qu’en est-il de l’indicateur d’ordre des octets ?

Si vous avez spécifié un indicateur d’ordre des octets (BOM) en UTF-8 au début de votre fichier, les navigateurs modernes l’utiliseront pour déterminer si votre page est encodée en UTF-8. Cet indicateur prévaudra sur toute autre déclaration, y compris sur l’en-tête HTTP.

Si vous spécifiez cet indicateur, vous n’avez pas besoin de déclarer l’encodage dans l’élément meta ; toutefois, nous vous recommandons de conserver cette déclaration, car elle permet aux personnes qui consultent votre code source de vérifier l’encodage de la page.

Découvrez plus d’informations sur l’indicateur d’ordre des octets.

Devrais-je déclarer l’encodage dans l’en-tête HTTP ?

Si cela a du sens et si vous en avez la possibilité, vous pouvez déclarer l’encodage de caractères dans l’en-tête HTTP pour tout type de contenu. Pensez toujours à utiliser également une déclaration à l’intérieur du document.

Si vous créez du contenu, vous devriez toujours vous assurer que les déclarations HTTP sont cohérentes avec les déclarations réalisées à l’intérieur du document.

Avantages et inconvénients de l’utilisation de l’en-tête HTTP

L’utilisation de l’en-tête HTTP présente un avantage : lorsque les informations d’encodage de caractères sont envoyées via l’en-tête HTTP, les agents utilisateurs peuvent les trouver plus vite.

Elle présente toutefois un certain nombre d’inconvénients potentiels :

  • Les personnes qui créent du contenu peuvent avoir du mal à modifier les informations d’encodage des fichiers statiques sur le serveur, surtout lorsqu’elles ont affaire à un FAI. Elles devront connaitre les paramètres du serveur et y avoir accès.

  • Les paramètres du serveur peuvent soudainement diverger des déclarations réalisées à l’intérieur du document pour une raison ou pour une autre. Par exemple, si vous utilisez les paramètres par défaut du serveur, ceux-ci peuvent être modifiés. Cette situation est dangereuse, car la prévalence des informations HTTP sur la déclaration réalisée à l’intérieur du document peut rendre le document illisible.

  • Des problèmes peuvent se poser pour les documents statiques et dynamiques lorsque ceux-ci ne sont pas lus à partir d’un serveur ; par exemple, s’ils sont enregistrés sur un support comme un CD ou un disque dur. Dans ces cas-là, aucune information d’encodage spécifiée dans un en-tête HTTP n’est disponible.

    De la même façon, si l’encodage de caractères n’est déclaré que dans l’en-tête HTTP, ces informations ne sont plus disponibles lorsque vous éditez vos fichiers, lorsqu’ils sont traités par XSLT ou par des scripts, lorsque vous les faites traduire, etc.

Devrais-je utiliser cette méthode ?

Si vous envoyez des fichiers via HTTP à partir d’un serveur, l’envoi d’informations sur l’encodage de caractères d’un document dans l’en-tête HTTP ne pose jamais problème, tant que ces informations sont exactes.

Toutefois, compte tenu des inconvénients listés ci-dessus, nous vous recommandons de toujours déclarer les informations d’encodage à l’intérieur du document en plus de le faire dans l’en-tête HTTP. Une déclaration réalisée à l’intérieur du document est également utile aux personnes qui souhaitent vérifier l’encodage d’un document à des fins de développement, de tests ou de gestion de projet de traduction.

(Certaines personnes estiment qu’il est rarement approprié de déclarer l’encodage dans l’en-tête HTTP si vous comptez le répéter dans le contenu du document. Dans ce cas, elles proposent de n’indiquer aucune information sur l’encodage du document dans l’en-tête HTTP. Cela signifie généralement qu’une action est nécessaire pour désactiver les paramètres par défaut du serveur.)

Travailler avec des formats polyglottes et XML

XHTML5 : un document XHTML5 utilise la syntaxe XML et est interprété en tant que XML. Les analyseurs syntaxiques XML ne reconnaissent pas les déclarations d’encodage réalisées dans l’élément meta. Ils ne reconnaissent que la déclaration XML. En voici un exemple :

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html ....

La déclaration XML est nécessaire lorsque la page n’est pas interprétée en tant que contenu UTF-8 (ou UTF-16). Lorsque la page est interprétée correctement, la déclaration est tout de même utile pour les personnes qui souhaiteraient vérifier l’encodage d’un document en consultant son code source. Cette information leur sera notamment utile à des fins de développement, de tests ou de gestion de projet de traduction.

Balisage polyglotte : une page qui utilise un balisage polyglotte utilise en fait un sous-ensemble de HTML avec la syntaxe XML qui peut être interprété par un analyseur syntaxique HTML ou XML. Ce cas de figure est décrit dans l’article Balisage polyglotte : un profil robuste du vocabulaire HTML5.

Un document polyglotte doit être encodé en UTF-8. Par conséquent, vous n’avez pas besoin de déclaration XML et ne devriez pas en utiliser. Toutefois, si un fichier doit être interprété comme du HTML, vous devrez en déclarer l’encodage à l’aide d’un élément meta, de l’indicateur d’ordre des octets ou de l’en-tête HTTP.

Toute déclaration réalisée dans un élément meta ne sera reconnue que par un analyseur syntaxique HTML. Par conséquent, si vous choisissez la méthode reposant sur l’attribut content, la valeur de celui-ci devra commencer par text/html;.

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

Si vous utilisez l’élément meta avec un attribut charset, vous n’aurez pas à vous poser cette question.

Informations complémentaires

Cette section comporte des informations dont vous ne devriez pas avoir besoin, mais que nous avons incluses à des fins d’exhaustivité.

Travailler avec des encodages autres qu’UTF-8

En plus de simplifier la création des pages, l’utilisation d’UTF-8 évite des résultats inattendus lors de l’envoi des formulaires et de la génération des URL, qui utilisent par défaut l’encodage de caractères du document. Si vous ne pouvez vraiment pas éviter l’utilisation d’un encodage de caractères autre qu’UTF-8, vous devrez choisir parmi un ensemble limité de noms d’encodages pour garantir la meilleure interopérabilité et la plus longue durée possible de lisibilité de votre contenu.

Encore récemment, vous deviez consulter le registre de l’IANA pour trouver les noms d’encodages. Ce registre mentionne un même encodage sous plusieurs noms ; le nom à utiliser figure dans la colonne « Preferred ».

De nos jours, vous devriez vous référer à la spécification Encodage, car elle fournit une liste de noms qui ont été testés dans des navigateurs réels. Vous pouvez trouver cette liste dans le tableau de la section intitulée Names and labels. Mieux vaut utiliser les noms indiqués dans la colonne de gauche de ce tableau.

Remarque : la présence d’un nom dans l’une de ces sources ne signifie pas forcément que cet encodage peut être utilisé. En effet, plusieurs de ces encodages sont problématiques. Si vous ne pouvez vraiment pas utiliser UTF-8, vous devriez lire avec attention les conseils de l’article Choisir et appliquer un encodage de caractères.

N’inventez pas vos propres noms d’encodages précédés de x-. C’est une mauvaise idée, car cette pratique limite l’interopérabilité.

Travailler avec d’anciens formats HTML

HTML 4.01 ne prévoit pas l’utilisation de l’attribut charset avec l’élément meta, mais les principaux navigateurs récents le détectent et l’utilisent tout de même, y compris lorsque la page déclare le format HTML4 au lieu de HTML5. Cette section n’est pertinente que si vous avez une bonne raison de vous conformer à un ancien format de HTML (autre que l’affichage dans un navigateur). Elle décrit les différences avec la section Réponse détaillée ci-dessus.

Pour les pages interprétées en tant que XML, consultez la section Travailler avec des formats polyglottes et XML.

HTML4 : comme nous venons de le voir, pour une conformité complète avec HTML 4.01, vous devez utiliser la directive pragma plutôt que l’attribut charset.

XHTML 1.x interprété en tant que text/html : pour une conformité complète avec HTML 4.01, l’utilisation de la directive pragma plutôt que l’attribut charset est également nécessaire. Vous n’avez pas besoin de déclaration XML, puisque ce fichier est interprété en tant que HTML.

XHTML 1.x interprété en tant que XML : utilisez l’attribut encoding de la déclaration XML à la première ligne de la page. Assurez-vous que rien ne se trouve avant cette déclaration, pas même des espaces. Seul un indicateur d’ordre des octets peut la précéder.

Ajouter l’attribut charset à un lien

En HTML5, l’ajout de l’attribut charset à un élément a ou link est désormais déconseillé. Vous devriez donc éviter cette pratique.

L’attribut charset trouve son origine dans la spécification HTML 4.01. On pouvait l’utiliser avec les éléments a, link et script pour indiquer l’encodage du document vers lequel pointait le lien. Il fallait l’ajouter à un élément lien intégré, comme sur l’exemple suivant :

XMauvais code. Ne pas copier  !
Consultez notre <a href="/monsite/mondoc.html" charset="iso-8859-15">liste de publications</a>.

Cet attribut devait permettre au navigateur d’appliquer le bon encodage au document qu’il récupérait si aucun encodage n’était spécifié par une autre méthode.

Toutefois, l’utilisation de cet attribut a toujours posé des problèmes. D’abord, sa compatibilité avec les principaux navigateurs laisse à désirer. Ceux-ci doivent en effet mettre en place des règles particulières pour éviter que cet attribut ne constitue un vecteur d’attaque par injection de code indirecte à distance (XSS). Ensuite, il est difficile de s’assurer que les informations restent correctes à tout moment. La personne qui a créé le document vers lequel pointe votre lien peut très bien modifier l’encodage du document sans vous en aviser. Si elle n’a toujours pas spécifié l’encodage de son document, vous allez donc demander au navigateur d’appliquer un encodage erroné. Enfin, cet attribut ne serait pas nécessaire si tout le monde suivant les lignes directrices présentées dans cet article et balisait correctement ses documents. Cette approche est largement préférable.

Cette manière d’indiquer l’encodage d’un document passe après toutes les autres. En d’autres termes, si l’encodage est déclaré d’une autre manière, quelle qu’elle soit, cet attribut sera ignoré. Cela signifie que vous ne pourriez pas non plus utiliser cet attribut pour corriger des déclarations erronées.

Travailler avec UTF-16

D’après les résultats d’une analyse effectuée par Google sur un échantillon constitué de plusieurs milliards de pages, moins de 0,01 % des pages web seraient encodées en UTF-16. D’après le même échantillon, plus de 60 % des pages web seraient encodées en UTF-8, et même plus de 80 % en incluant son sous-ensemble, ASCII. Nous vous recommandons vivement de ne pas choisir l’encodage UTF-16 pour vos pages.

Toutefois, si vous n’avez pas le choix pour quelque raison que ce soit, voici quelques règles à suivre pour déclarer cet encodage. Ces règles ne sont pas les mêmes que pour les autres encodages.

La spécification HTML5 interdit l’utilisation de l’élément meta pour déclarer l’encodage UTF-16, car les valeurs doivent être compatibles avec ASCII. Au lieu d’utiliser cet élément, vous devriez toujours placer un indicateur d’ordre des octets au tout début de chaque fichier encodé en UTF-16. Il s’agit donc d’une déclaration réalisée à l’intérieur du document.

Par ailleurs, si votre page est encodée en UTF-16, ne déclarez pas que votre fichier utilise l’encodage « UTF-16BE » ou « UTF-16LE », mais seulement « UTF-16 ». L’indicateur d’ordre des octets présent au début de votre fichier spécifiera si le mécanisme de sérialisation est petit-boutiste ou gros-boutiste. En effet, le contenu explicitement encodé en UTF-16BE (par exemple) ne devrait pas contenir d’indicateur d’ordre des octets ; en revanche, HTML5 exige la présence de cet indicateur au début des pages encodées en UTF-16.