この記事を見て初めて知った。

https://blog.w0s.jp/639

よく記述する下記の指定はHTML5から使用できるものだそうだ。

<meta charset="UTF-8">

HTML4以前はこちらを使っており、HTMLの黎明期にはmeta要素がなかったそうだ。

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

またこの文字エンコーディングの指定は現在はUTF-8以外の値は禁止されている。

Content-Typeヘッダーとmeta要素の優先度

基本的な考え方は HTML 2.x 時代から変わらず、 Content-Type ヘッダーの charset パラメーターで文字エンコーディングが指定されていれば、 <meta> 要素による指定は必要ありません。両方が指定された場合、 Content-Type ヘッダーの指定が優先されます。

過去には Content-Type ヘッダー、 <meta> 指定、 charset 属性の3パターンの優先度を考慮すべき時代もありました。HTML 4.01 仕様の5.2.2 Specifying the character encoding(www.w3.org)ではその3つの優先度が書かれています。しかし charset 属性は HTML5 で廃止されたので、現在では「Content-Type ヘッダーは <meta> 要素より優先する」ことだけ覚えておけば大丈夫でしょう。

https://blog.w0s.jp/639

と記載されており、Content-typeヘッダー > meta指定であることが記載されている。

ブラウザの挙動を考えると、リクエスト時に未加工のバイトをどのような文字コードに基づき変換するかを指定する必要があるので、レスポンスのContent-Typeヘッダーを先に参照し、そこに書かれていなければHTMLのmetaタグを見るという順番は納得がいく。


また

Content-Type ヘッダーで charset パラメーターが指定されている場合は <meta> 要素での文字エンコーディングの指定は任意です。 HTML をファイルとしてダウンロードしてオフラインで閲覧されるケースまで想定するなら、指定するメリットはあるかもしれません。

一方でデメリットも存在します。

前述のとおり、 HTML4 では「<meta> 要素による文字エンコーディング指定より前に非 ASCII 文字を含めることができない」という制限がありました。現在の HTML では ASCII 範囲内かそうでないかに関係なく、より具体的な挿入範囲が明記されています。

https://blog.w0s.jp/639

文字エンコーディング宣言を含む要素は、文書の最初の1024バイト内に完全にシリアル化されなければならない。

4.2.5.4 文書の文字エンコーディングを指定する

とも書いており、PWAなどを考えると meta要素の指定を入れておいたほうが無難であるようだ。
ただHTML5では1024バイトまではmeta要素の前に文字をいれることが可能(HTML4ではASCIIのみ)という制限があるため、なにか特殊なことを行う際は注意する必要がある。
※ただし、content-typeヘッダーを指定したうえでmeta指定を削除するのであれば、その制限もなくなる

このようなデメリットもあるので、 <meta> 要素による文字エンコーディング指定は何も考えずコピペで挿入するのではなく、メリットとデメリットを天秤に掛けたうえで慎重に判断されるべきでしょう。

ちなみに、あまりにも <meta> 要素の挿入が当たり前になってしまったが故に、まるで <meta> 要素が必須であるような事実誤認も一部には見られるようです。実際、私は( .htaccess ファイルで charset パラメーターの設定を書いたうえで) <meta> 要素なしの HTML を納品した際、客先から「<meta> も書けないなんてお前は素人か」といったクレームを頂いてしまったこともあるので[9]、まあその辺も鑑みて事前に意識をすり合わせるくらいのことは必要かもしれません。

https://blog.w0s.jp/639

とのことで、自分がHTML弱者であることを思い知ったすばらしい記事でした。

ちなみに.htaccessでContent-Typeヘッダーのcharsetパラメーターを指定する場合は下記のようになる。

AddDefaultCharset UTF-8

あるいは

AddType "text/html; charset=UTF-8" .html .php